【问题标题】:Rails Unique Constraints Model + Database Level and Race ConditionsRails 独特的约束模型 + 数据库级别和竞争条件
【发布时间】:2017-09-03 10:14:22
【问题描述】:

我的 UserGroups has_many 目前有以下迁移:通过关联:

class CreateUserGroups < ActiveRecord::Migration
  def change
    create_table :user_groups do |t|
      t.integer :user_id, :null => false
      t.integer :group_id, :null => false
      t.timestamps null: false
    end
  end
end

具有以下模型和唯一约束:

class UserGroup < ActiveRecord::Base
  belongs_to :user
  belongs_to :group
  validates_uniqueness_of :user, :scope => :group, :message => :not_unique
end

唯一性验证效果很好,但是如果我的应用程序中的竞争线程导致竞争条件并且它通过了应用程序级别的检查怎么办?如何编写迁移以防止数据库级别的用户和组在我的联接表中出现重复行?

【问题讨论】:

    标签: mysql ruby-on-rails postgresql activerecord rails-migrations


    【解决方案1】:

    你需要添加一个唯一索引

    add_index :user_groups, [:user_id, :group_id], unique: true
    

    【讨论】:

    • 就这样吗?这会双向工作,还是如果一个组添加一个用户/用户添加一个组?
    • 是的,它是双向的。
    • 顺序与唯一性无关,但是仅在查询第一列或两者时才使用索引。这将用于select * from user_groups where user_id = 1,但不适用于select * from user_groups where group_id = 1
    • 但是请注意,如果违反了数据库中的唯一约束,而不是简单地以通常的方式验证失败,这将引发ActiveRecord::RecordNotUnique 异常。
    • 好吧,您不需要两个唯一索引,所以只需添加 add_index :user_groups , [:group_id][:group_id, :user_id]
    猜你喜欢
    • 2012-04-08
    • 1970-01-01
    • 2011-02-05
    • 2018-03-19
    • 1970-01-01
    • 2013-08-12
    • 2017-02-10
    • 2013-05-09
    • 1970-01-01
    相关资源
    最近更新 更多