我有2个模型,如下所示,
根据建议更新
class User < ActiveRecord::Base
has_many :company_users, dependent: :destroy, inverse_of: :user
accepts_nested_attributes_for :company_users, allow_destroy: true
has_many :companies, through: :company_users
has_many :roles, through: :company_users
end
和
class CompanyUser < ActiveRecord::Base
belongs_to :company
belongs_to :role
belongs_to :user, inverse_of: :company_users
validates :user, uniqueness: {scope: [:company, :role]}
end
我发现唯一性验证仅适用于update
请求。在create
请求验证无法正常运行,它只是绕过它。
如果用户拥有相同的公司,我想启用相同的验证来拒绝角色分配不止一次。
答案 0 :(得分:1)
如果您希望确保用户在唯一一对:company和:role上的唯一性,那么您可以尝试以下操作。默认情况下,将为create和update运行验证。你不需要:on => [ :create, :update ]
。所以应该只是:
validates :user, uniqueness: {scope: [:company, :role]}
答案 1 :(得分:1)
通过以下验证解决了这个问题,
class User < ActiveRecord::Base
has_many :company_users, dependent: :destroy, inverse_of: :user
accepts_nested_attributes_for :company_users, allow_destroy: true
has_many :companies, through: :company_users
has_many :roles, through: :company_users
validate :company_users, :uniqueness_of_company_users
end
private
def uniqueness_of_company_users
errors.add(:company_users, 'error in role creation') if company_users.map{|x| "#{x.company_id} #{x.role_id}"}.uniq.size != company_users.size
end
这是解决问题所需的额外验证
感谢Rich Peck为此https://railscoding.wordpress.com/2015/04/27/uniqueness-gotcha/
答案 2 :(得分:0)
来自docs
:on选项需要一个值
:create
或:update
-
验证仅 在create
或update
上运行,对吗?
find
没有操纵数据库,destroy
摆脱了记录&amp; new
只调用该对象的新实例。您确实没有其他理由可以验证。
所以,真的,你应该:
validates :user, uniqueness: {scope: [:company_id, :role_id]}
这会查看company_id
和role_id
中的值,这可能比调用company
和role
对象本身更有效。
我可能错了,但我真的认为如果你使用了上述内容,它应该可以运作。
-
您可能还希望清理模型:
class User < ActiveRecord::Base
has_many :company_users, dependent: :destroy, inverse_of: :user
accepts_nested_attributes_for :company_users, allow_destroy: true
has_many :companies, through: :company_users
has_many :roles, through: :company_users
end
class CompanyUser < ActiveRecord::Base
belongs_to :company
belongs_to :role
belongs_to :user, inverse_of: :company_users
validates :user, uniqueness: {scope: [:company_id, :role_id]}
end