拒绝嵌套的assosciation创建rails

时间:2015-12-19 00:02:39

标签: ruby-on-rails ruby-on-rails-4 activerecord

我有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请求验证无法正常运行,它只是绕过它。

如果用户拥有相同的公司,我想启用相同的验证来拒绝角色分配不止一次。

3 个答案:

答案 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

-

验证仅 createupdate上运行,对吗?

find没有操纵数据库,destroy摆脱了记录&amp; new只调用该对象的新实例。您确实没有其他理由可以验证。

所以,真的,你应该:

validates :user, uniqueness: {scope: [:company_id, :role_id]}

这会查看company_idrole_id中的值,这可能比调用companyrole对象本身更有效。

我可能错了,但我真的认为如果你使用了上述内容,它应该可以运作。

-

您可能还希望清理模型:

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