多列外键Ruby on Rails



我有以下模型:

公司、订单、发票

公司有很多订单,也有很多发票。订单有一个发票,属于一个公司。发票属于订单和公司。因此,订单引用company_id,发票引用company_id。我想确保发票company_id与其父订单的company_id相同。

注意:Postgres支持这个。如何使用rails来实现?https://www.postgresql.org/docs/9.3/ddl-constraints.html DDL-CONSTRAINTS-FK

  1. 我将创建一个外键,以确保发票order_id + company_id存在于订单id + company_id?
  2. 实现这一目标的最佳方法是什么?
  3. 这可以通过迁移来完成吗?

YAGNI

你想得太多了,把事情弄得太复杂了。相反,您可以做的是消除由invoices.company_id引起的不必要的重复,并仅设置间接关联:

class Company < ApplicationRecord
has_many :orders
has_many :invoices, through: :orders
end
class Order < ApplicationRecord
belongs_to :company
has_many :invoices
end
class Invoice < ApplicationRecord
belongs_to :order
# joins the company through the orders.company_id column
has_one :company, 
through: :order
end

这完全避免了整个问题,您所需要的只是由references/belongs_to迁移宏创建的简单外键。

虽然你所建议的也许可以通过复合外键来完成,但这种方法并没有实际的优势。

这可以通过迁移来完成吗?

迁移DSL实际上不支持它,但您总是可以运行任意SQL。但是,Ruby模式转储器在解析模式时很可能无法复制它,因此外键将"在翻译中丢失"。当从模式重新创建db时,除非您切换到SQL模式转储。

def up
execute <<-SQL
ALTER TABLE invoices
ADD CONSTRAINT fk_invoices_orders_order_id_company_id
FOREIGN KEY (order_id, company_id)
REFERENCES orders(id, company_id)
ON DELETE RESTRICT
SQL
end
def down
execute <<-SQL
ALTER TABLE invoices
DROP CONSTRAINT fk_invoices_orders_order_id_company_id
SQL
end

最新更新