简体   繁体   English

唯一性验证不适用于has_many:尽管在Rails 5上具有关联

[英]Uniqueness validation not working on has_many :though association on rails 5

Models 楷模

class User < ApplicationRecord
    has_many :memberships
    has_many :pages, through: :memberships 
end

class Page < ApplicationRecord
    has_many :memberships
    has_many :users, through: :memberships 
end

class Membership < ApplicationRecord
    belongs_to :user
    belongs_to :page

    validates :page_id, uniqueness: { scope: :user_id}
end

Am able to create multiple user on pages and pages on user, it's like the validation isn't getting called. 能够在页面和用户页面上创建多个用户,就像没有调用验证一样。

To trigger the validations in a associated model you need to use validates_associated : 要在关联模型中触发验证,您需要使用validates_associated

class User < ApplicationRecord
  has_many :memberships
  has_many :pages, through: :memberships
  validates_associated :memberships
end

class Page < ApplicationRecord
  has_many :memberships
  has_many :users, through: :memberships
  validates_associated :memberships
end

class Membership < ApplicationRecord
  belongs_to :user
  belongs_to :page
  validates :page_id, uniqueness: { scope: :user_id}
end

This can be a real gotcha as validations on associations are not called when they are created implicitly. 这可能是一个真正的陷阱,因为隐式创建关联时不会调用它们的验证。

Additionally its a good idea to create a compound database index which prevents possible race conditions : 另外,创建一个复合数据库索引以防止可能出现的竞争状况是一个好主意:

class AddCompoundIndexToMemberships < ActiveRecord::Migration[5.0]
  def change
    add_index :memberships, [:page_id, :user_id], unique: true
  end
end

This ensures on the DB level that no two identical rows can be created. 这样可以确保在数据库级别上无法创建两个相同的行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM