【发布时间】:2018-02-14 04:04:01
【问题描述】:
我正在制作一个医院应用程序,其中有 health_problems,它们由 patient_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_id 和 patient_id 索引设置为唯一,但没有按预期工作(即使使用不同的问题类型/患者,我也无法添加任何重复的问题类型/患者)
更新:我错误地添加了索引。
正如@mmichael 所指出的,这是添加索引的正确方法:
add_index :health_problems, [:patient_id, :problem_type_id], unique: true
现在数据库向我抛出一个错误,阻止它为一名患者添加重复的问题类型。这是一个进步,但仍然不是我需要的。
我需要通过 rails 验证来显示此错误(以一种可以正确处理的方式)。
更新 2:当使用 accepts_nested_attributes_for + validates uniqueness with scope 时,它看起来像 known rails bug。
为多个列创建唯一索引将防止添加重复项,但是 - 在此版本的 Rails (5.1) 之前 - 验证将分两次显示:首先是 sql 重复验证,然后是您的模型具有的其他验证。
由于这只能在数据库级别进行验证,因此不需要模型验证 (validates :problem_type_id, uniqueness: {scope: :patient_id})。希望 Rails 团队尽快修复它。
数据库错误可以用rescue_from处理。
【问题讨论】:
-
当您说您尝试添加唯一索引时,您是否尝试过
add_index :health_problems, [:patient_id, :problem_type_id], unique: true? -
@mmichael 实际上我正在添加单独的索引(这是一个错误)。你说的方式如我所愿,但它只在数据库中验证,它返回:“Mysql2::Error: Duplicate entry '6-3' for key 'index_health_problems_on_patient_id_and_problem_type_id'”我需要它来返回一个验证错误。
-
假设您在创建 HealthProblem 记录时使用
accepts_nested_attributes_for,有一个带有各种解决方法的 known rails issue。我建议您从创建记录的任何地方从ActiveRecord::RecordNotUnique中解救出来。如果您在控制器中执行此操作,请查看rescue_from,或者您可以简单地将您的记录创建块包装在标准rescue中。 -
没错,我正在使用
accepts_nested_attributes_for,它看起来像你指出的一个rails错误。对您的回答有很大帮助,谢谢。 -
不客气
标签: ruby-on-rails validation ruby-on-rails-5