多条记录上的 activerecord 唯一约束

activerecord unique constraint on multiple records

我应该如何编写 activerecord 迁移来反映这一点:

CREATE TABLE table (
    c1 data_type,
    c2 data_type,
    c3 data_type,
    UNIQUE (c2, c3)
);

This adds a unique constraint on one column, but what I'm looking for is to create the unique constraint on the combination of 2 columns, like explained in the section Creating a UNIQUE constraint on multiple columns.

编辑

更准确地说:我有一个 table 帐户和一个 table balance_previous_month。

class CreateBalance < ActiveRecord::Migration[6.1]
  def change    
        create_table :balance_previous_month do |t|
        t.decimal :amount, :precision => 8, :scale => 2
        t.date :value_date
        t.belongs_to :account, foreign_key: true
        t.timestamps
    end
  end
end

由于我们是在 1 月,起息日(即上个月末的余额)为 2020-12-31

我想对 table balance_previous_month 进行限制,其中每个 account_id,只能有一个 value_date 具有给定的数量。金额可以更新,但给定帐户不能有 2 个相同的 value_dates.

您添加到另一个 post 的 link 并不完全等同于您的请求,因为一个答案谈论通过模型强制执行唯一性,而另一个谈论在您的示例中使用索引您正在使用约束。 (检查 this 以获取有关它们之间差异的更多信息)。

有 2 个地方可以强制唯一性,应用程序和数据库,也可以同时在两个地方执行。

数据库

所以如果你想通过使用索引来强制唯一性,你可以使用这个:

def change
  add_index :table, [:c2, :c3], unique: true
end

如果您想像示例中那样添加 约束,您将必须 运行 在迁移中直接 sql 查询,因为没有rails 中的内置方式可以做到这一点。

def up
  execute <<-SQL
    ALTER TABLE table
    ADD UNIQUE (c2, c3)
  SQL
end

查看上面的 link 以了解有关它们之间差异的更多信息。

申请

通过模型强制唯一性:

validates :c2, uniqueness: { scope: :c3 }

感谢 Daniel Sindrestean,此代码有效:

class CreateBalance < ActiveRecord::Migration[6.1]
  def change    
        create_table :balance_previous_month do |t|
        t.decimal :amount, :precision => 8, :scale => 2
        t.date :value_date
        t.belongs_to :account, foreign_key: true
        t.timestamps
    end
    execute <<-SQL
        ALTER TABLE balance_previous_month
        ADD UNIQUE (account_id, value_date) # ActiveRecord creates account_id
    SQL
  end
end