Vla*_*ski 2 ruby validation ruby-on-rails unique conditional-statements
我在播放列表模型中进行了以下验证,其中包含属性title和is_deleted.'is_deleted'列(bool类型列,默认值为'false')的要点是因为我必须存档播放列表而不删除它们.
validates :title, presence: true, uniqueness: true, unless: :is_deleted?
Run Code Online (Sandbox Code Playgroud)
现在,如果我有一个标题为'播放列表1'并且is_deleted为false的记录并尝试使用is_deleted创建一条记录:true它将不会验证他,这很好.如果我尝试将is_deleted列从第一个记录更新为true,它将不会验证,这也是好的.
但现在我有两个标题播放列表:"播放列表1"和is_deleted:true.如果我尝试将它们中的任何一个更新为is_deleted:false,验证将不会让我.它给出了"标题已被采取"错误.我真的不明白为什么,因为我没有任何其他记录是is_deleted:false标题:"播放列表1".
这是因为您的验证仅检查唯一性:title
.在更改is_deleted
为模型后验证模型时,false
检查标题是否唯一.它会进行如下查询:
Playlist.where(title: 'Playlist 1').where.not(id: self.id).exists?
Run Code Online (Sandbox Code Playgroud)
显然已经有一个带有该标题的播放列表.
关键是它不会检查其他播放列表is_deleted
上的标志.它仅在当前播放列表中使用它来决定是否应该验证.
您可能需要我们validates_uniqueness_of
而不仅仅是validates
这意味着您可以为验证添加条件:
validates_uniqueness_of :title,
unless: :is_deleted?,
conditions: -> { where(is_deleted: false) }
Run Code Online (Sandbox Code Playgroud)
这将确保您的唯一性检查仅检查也未删除的其他播放列表.
您需要保持validates :title, presence: true, unless: :is_deleted?
验证标题是否存在(或者您可以使用allow_nil
或allow_blank
选项取得一些成功validates_uniqueness_of
).
归档时间: |
|
查看次数: |
808 次 |
最近记录: |