我有两个具有HABTM关系的模型 – 用户和角色.
> user – has_and_belongs_to_many:roles
> role – belongs_to:user
我想在join(users_roles表)中添加一个唯一性约束,表示user_id和role_id必须是唯一的.在Rails中,会像:
validates_uniqueness_of :user,:scope => [:role]
当然,在Rails中,我们通常不会有一个模型来表示HABTM关联中的连接关系.
那么我的问题是添加约束的最佳位置在哪里?
解决方法
您可以添加唯一性来连接表
add_index :users_roles,[ :user_id,:role_id ],:unique => true,:name => 'by_user_and_role'
见In a join table,what’s the best workaround for Rails’ absence of a composite key?
您的数据库将引发异常,然后您必须处理该异常.
我不知道这种情况下可以使用rails验证,但是您可以添加自己的验证,如下所示:
class User < ActiveRecord::Base has_and_belongs_to_many :roles,:before_add => :validates_role
def validates_role(role) raise ActiveRecord::Rollback if self.roles.include? role end
ActiveRecord :: Rollback在内部被捕获但不被重新编译.
编辑
不要使用我添加自定义验证的部分.它有点工作,但有更好的选择.
使用:在另一个答案中建议的@Spyros关联的uniq选项:
class Parts < ActiveRecord::Base has_and_belongs_to_many :assemblies,:uniq => true,:read_only => true end
(此代码片段来自Rails Guides v.3).阅读Rails Guides v 3.2.13寻找4.4.2.19:uniq
Rails指南v.4具体警告不要使用include?用于检查由于可能的竞争条件的唯一性.
关于添加索引到连接表的部分停留.