Rails 4 HABTM对关联的自定义验证

时间:2014-07-03 17:00:49

标签: ruby-on-rails validation activerecord ruby-on-rails-4 has-and-belongs-to-many

我有一个简单的场景,但我似乎无法找到适用于Rails 4的任何建议的解决方案。我想简单地添加一个自定义验证器来检查我的HABTM之间存储的关联量协会。令我惊讶的是,更容易说完了吗?

我已经搜索了一个解决方案,但最终只得到了旧版本Rails的答案。我得到了以下内容:

class User < ActiveRecord::Base

  has_and_belongs_to_many :roles
  after_save :check_maximum_number_of_roles

  .
  .
  .

  private

  def check_maximum_number_of_roles
    if self.roles.length > 3
      errors.add(:roles, 'Users can only have three roles assigned.')
      return false
    end
  end

end

class Role < ActiveRecord::Base

  has_and_belongs_to_many :users

end

我使用after_save的原因是因为据我所知,存储的关联在添加后首先可用。我还尝试编写自定义验证器(例如validate: :can_only_have_one_role),但这也不起作用。

我按以下方式添加关联,并在rails控制台中完成此操作(应该可以正常工作吗?):

user.roles << role

然而,它为用户添加了多个角色,并不关心任何类型的验证。

非常感谢,谢谢!

1 个答案:

答案 0 :(得分:9)

user.roles << role不会对user执行任何验证。用户基本上没有参与。所有这一切都是在您的加入表中插入一条新记录。

如果你想强制用户只有一个角色,你有两个选择,都涉及丢弃has_and_belongs_to_many,你真的不应该再使用它了。 Rails提供has_many :through,这是一段时间内做多对多关系的首选方式。

所以,第一种(我认为最好的)方法是使用has_many / belongs_to。这就是你在Rails中建立一对多关系的方法。应该这么简单:

class Role
  has_many :users
end

class User
  belongs_to :role
end

第二种方法是强制执行单个关联记录,它是创建您的加入模型,称之为UserRole,使用has_many :through,并在{{1}内执行验证}。

UserRole