ActiveRecord验证:关联的唯一性

时间:2012-01-05 07:49:40

标签: ruby-on-rails ruby validation activerecord

我需要执行验证以确保公司中只有一个用户可以存在于给定类别中。

  validates  :user_id, :uniqueness => {:scope => [:category, :company_id], :message => "already exists"}

除了在:user_id密钥上设置错误消息外,这是有效的。

如何执行相同操作但在:user键上设置错误(validates :user会出错?)

2 个答案:

答案 0 :(得分:8)

这是检查唯一性并强制将错误分配给:user属性的简单方法:

class User < ActiveRecord::Base
  validate :user_unique_per_company_per_category

  private

  def user_unique_per_company_per_category
    if self.class.exists?(:user_id => user_id, :company_id => company_id, :category => category)
      errors.add :user, 'already exists'
    end
  end
end

我认为,如果你能找到一种方法在:user_id上使用默认验证,那将是更好的选择,但也许你有一个特殊的用例。

此外,如果您未在表单中使用此功能,则可以考虑将错误分配给:base,因为您可能会混淆期望错误出现在:user_id上的未来开发人员:

errors.add :base, 'already exists'

答案 1 :(得分:-1)

我不认为这是可能的,因为ActiveRecord 的验证方法将错误发送到正在验证的方法。

如此验证:用户尝试发送到用户的attr_accessor,这在您的模型中不存在。

但是,如果你只是想让错误信息变得漂亮,你可以:

alias user user_id

然后在验证中使用:user。

validates  :user, :uniqueness => {:scope => [:category, :company_id], :message => "already exists"}

另外,我不会在别名中使用user,而是使用:

alias the_supplied_user user_id

然后在你的验证中:

validates  :the_supplied_user, :uniqueness => {:scope => [:category, :company_id], :message => "already exists"}