Ruby on rails 如何验证Rails 5中的组合值?
我正在制作一个医院应用程序,其中有Ruby on rails 如何验证Rails 5中的组合值?,ruby-on-rails,validation,ruby-on-rails-5,Ruby On Rails,Validation,Ruby On Rails 5,我正在制作一个医院应用程序,其中有健康问题,由患者id和问题类型组成 一名患者可以有多个健康问题,但不能属于同一问题类型 创建患者时,我将其健康问题创建为嵌套属性。但是验证不会阻止我为一名患者创建重复的问题类型 这是我的健康问题模型: class HealthProblem < ApplicationRecord belongs_to :patient belongs_to :problem_type validates :problem_type_id, uniqueness
健康问题
,由患者id
和问题类型
组成
一名患者可以有多个健康问题
,但不能属于同一问题类型
创建患者时,我将其健康问题
创建为嵌套属性。但是验证不会阻止我为一名患者创建重复的问题类型
这是我的健康问题模型:
class HealthProblem < ApplicationRecord
belongs_to :patient
belongs_to :problem_type
validates :problem_type_id, uniqueness: {scope: :patient_id}
end
类健康问题
我还尝试将问题类型\ id
和患者\ id
索引设置为唯一,但没有按预期工作(即使问题类型/患者不同,我也无法添加任何重复的问题类型/患者)
更新:我添加索引时出错。 正如@mmichael所指出的,这是添加索引的正确方法:
添加索引:健康问题,[:患者id,:问题类型id],唯一性:true
现在数据库向我抛出一个错误,阻止它为一个患者添加重复的问题类型。这是一个进步,但仍然不是我需要的
我需要rails验证来显示这个错误(在某种程度上可以正确处理)
更新2:当使用
接受
+的嵌套属性时,它看起来像一个,验证作用域的唯一性
为多列创建唯一索引将防止添加重复项,但是在Rails(5.1)版本发布之前,验证将分两次显示:首先是sql重复验证,然后是模型的其他验证
由于这只能在数据库级别进行验证,因此不需要进行模型验证(验证:problem_type_id,惟一性:{scope::patient_id}
)。希望Rails团队尽快修复它
数据库错误可以处理。我在Rails 5.1.5
上也遇到了这个问题。我的解决方案是将一个独特的数据库索引(如@artur haddad建议的)与模型arou save
回调结合使用。我将试着用一个简短的提纲来解释我的问题和解决方案
问题:
Institution (id:integer, name:string)
| 1
|
| *
WaterSupply (id:integer, meter:string, institution_id:integer)
因此,一个机构
可能有许多供水
,每个供水
都需要一个唯一的水表
参考。在我使用的常用表格中编辑供水
accepts_nested_attributes_for :water_supplies, reject_if: :all_blank, allow_destroy: true
在这一点上,验证
validates :meter, uniqueness: {scope: :institution_id}
在供水系统中,由于出现故障,供水系统不再工作
解决方案:
Institution (id:integer, name:string)
| 1
|
| *
WaterSupply (id:integer, meter:string, institution_id:integer)
将唯一的数据库索引添加到表water\u supplies
add_index :water_supplies, [:meter, :institution_id], unique: true
在保存前后添加model回调
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
class供水
就这些。现在,如果属性meter
在给定范围内不再是唯一的,则每次保存时都会得到一个ActiveModel::Error
,并且表单将显示已经发生的错误当您说您已经尝试添加唯一索引时,您是否尝试过添加索引:健康问题,[:患者id,:问题类型id],唯一:true
?@mmichael实际上我添加了单独的索引(这是一个错误)。您所说的方式如我所愿,但它只在数据库中进行验证,它返回:“Mysql2::Error:key‘index_health_problems_on_patient_id_和_problem_type_id’的重复条目‘6-3’”我需要它返回验证错误。假设您在创建健康问题记录时使用接受
的嵌套属性,有一个包含各种解决方法的解决方案。我建议您从创建记录的任何位置营救ActiveRecord::RecordNotUnique
。如果您在控制器中执行此操作,请查看,或者您可以简单地将您的记录创建块包装在标准的rescue
中。没错,我使用的是接受嵌套的属性,正如您所指出的,它看起来像rails bug。非常感谢您的回答。很好。当我使用此方法时,我会收到“ActiveRecord::RecordNotSaved:未能保存记录”当我使用此方法并尝试创建具有两个嵌套记录的父级时,未保存的父级模型仍然有一个id和持久性方法,如#new#U record?而#坚持?这是不正确的。