gpt4 book ai didi

ruby-on-rails - 如何验证 Rails 5 中的组合值?

转载 作者:行者123 更新时间:2023-12-01 01:49:04 25 4
gpt4 key购买 nike

我正在制作一个医院应用程序,并且有 health_problemspatient_id 组成和一个 problem_type_id .

一个病人可以有多个 health_problems但它们不能相同 problem_type_id .

当我创建一个病人时,我创建了它的 health_problems作为嵌套属性。但验证是 不停止我从创建重复 problem_types对于一名患者。

这是我的 HealthProblem 模型:

class HealthProblem < ApplicationRecord
belongs_to :patient
belongs_to :problem_type
validates :problem_type_id, uniqueness: {scope: :patient_id}
end

我也尝试设置 problem_type_idpatient_id索引的唯一性,但它没有按预期工作(即使有不同的问题类型/患者,我也无法添加任何重复的问题类型/患者)

更新:我错误地添加了索引。
正如@mmichael 所指出的,这是添加索引的正确方法: add_index :health_problems, [:patient_id, :problem_type_id], unique: true
现在数据库向我抛出一个错误,阻止它为一名患者添加重复的问题类型。这是一个进步,但仍然不是我需要的。

我需要通过 rails 验证显示此错误(以某种方式可以正确处理)。

更新 2:它看起来像一个 known rails bug , 使用时 accepts_nested_attributes_for + validates uniqueness with scope .

为多个列创建唯一索引将防止添加重复项,但是 - 在此版本的 Rails (5.1) 之前 - 验证将显示两次:首先是 sql 重复验证,然后是模型具有的其他验证。

由于这只能在数据库级别进行验证,因此不需要模型验证 ( validates :problem_type_id, uniqueness: {scope: :patient_id} )。希望 Rails 团队尽快修复它。

数据库错误可以用 rescue_from 处理.

最佳答案

我也在 Rails 5.1.5 上遇到了这个问题.我的解决方案是将唯一的数据库索引(如@artur-haddad 提出的)与模型 around_save 结合使用。打回来。我将尝试将我的问题和解决方案解释为一个简短的大纲。

问题:

Institution (id:integer, name:string)
| 1
|
| *
WaterSupply (id:integer, meter:string, institution_id:integer)

所以一个 Institution可能有很多 water_supplies和每个 WaterSupply需要一个独特的 meter引用。编辑 water_supplies在我使用的通用形式中
accepts_nested_attributes_for :water_supplies, reject_if: :all_blank, allow_destroy: true

此时验证
validates :meter, uniqueness: {scope: :institution_id}

WaterSupply 不再工作 由于 known issue .

解决方案:
  • 将唯一的数据库索引添加到表 water_supplies
    add_index :water_supplies, [:meter, :institution_id], unique: true
  • 添加 around_save模型回调
    class WaterSupply < ApplicationRecord
    # Associations
    belongs_to :institution

    # Validations
    validates :institution, :meter, presence: true

    # Callbacks
    around_save :catch_uniqueness_exception

    private

    def catch_uniqueness_exception
    yield
    rescue ActiveRecord::RecordNotUnique
    self.errors.add(:meter, :taken)
    end
    end

  • 就这样。现在属性 meter得到一个 ActiveModel::Error在每次保存时,如果它在给定范围内不再是唯一的,并且表单将显示错误 already taken .

    关于ruby-on-rails - 如何验证 Rails 5 中的组合值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46062085/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com