【问题标题】:How do you add a custom uniqueness validation to an ActiveRecord model in Rails?如何在 Rails 中为 ActiveRecord 模型添加自定义唯一性验证?
【发布时间】:2017-07-18 04:26:06
【问题描述】:
我在阅读Ruby on Rails Guides article on ActiveRecord validations 时发现了这个关于uniqueness 验证的简洁摘录:
还有一个 :case_sensitive 选项可用于定义唯一性约束是否区分大小写。此选项默认为 true。
这是一个非常有用的功能,可以确保两个用户不能使用相同的用户名或电子邮件注册,例如。但是,我想使用类似的验证,但使用不同的方法来确定字符串的相等性。我想确保我的所有条目在squeeze 下都是唯一的。
例如,假设我的Post 模型有一个文本属性content。我想确保如果foo bar 已经在数据库中,它不会接受foo bar 或foo bar。除了添加自定义验证来迭代Post.all、squeezeing 每个条目并将其与squeezed content 进行比较之外,还有更好的方法吗?我无法想象它可以很好地扩展。
【问题讨论】:
标签:
ruby-on-rails
ruby
validation
rails-activerecord
【解决方案1】:
您可以在 posts 表中添加另一个名为 squeezed_content 或类似名称的列,然后执行以下操作以使用内置的唯一性验证:
class Post < ActiveRecord::Base
before_save :set_squeezed_content
validates :squeezed_content, uniqueness: true
def set_squeezed_content
self.squeezed_content = content.squeeze
end
end
【解决方案2】:
虽然您可能会尝试以“Rails”方式完成所有工作,但在这种特殊情况下,我会走另一条路。如果出于某种原因您想在数据库中保留“foo bar” 内容,只需引入一个新字段squeezed_content,实现post_commit 挂钩以使用压缩值content 更新此字段并暗示对该新字段进行验证引入了squeezed_content 字段,强制它是唯一的。
您也可能只存储已经压缩的值。