activerecord对多个记录的唯一约束



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

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

这在一列上添加了唯一约束,但我想要的是在两列的组合上创建唯一约束,就像在多列上创建唯一约束一节中所解释的那样。

编辑

更准确地说:我有一个表account和一个表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

由于我们是在一月份,所以价值日期(即上月底的余额)是2020-12-31

我想在表balance_previous_month上添加一个约束,其中每个account_id只能有一个给定数量的value_date。金额可以更新,但给定的帐户不能有两个相同的value_dates。

您添加到另一个帖子的链接并不完全等同于您的请求,因为一个答案谈论通过模型强制唯一性,而另一个谈论使用索引,而在您的示例中,您正在使用约束。(点击这里了解更多关于它们之间区别的信息)

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

数据库

所以如果你想通过使用索引来强制唯一性你可以这样写:
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

查看上面的链接,了解更多关于它们之间区别的信息。

应用

通过模型强制惟一性:

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

相关内容

  • 没有找到相关文章

最新更新