可以在续集ORM中使用`one_to_many_through`关联吗?

时间:2016-01-06 10:15:49

标签: ruby orm sequel

我有一个案例,其中一个模型与另外两个模型相关。我正在尝试正确设置这3个模型之间的模型关系。

简化示例...前两个表格为clientsinvoices

db.create_table(:clients) do
    primary_key :id
    String :name
end

db.create_table(:invoices) do
    primary_key :id
    String :description
    Integer :balance
end

第三个表名为files,包含可与clientsinvoices相关的文件记录:

db.create_table(:files) do
    primary_key :id
    String :name
    String :path
    String :type # [image, pdf, word, excel]
end

有2个连接表可以将files连接到clientsinvoices

db.create_table(:clients_files) do
    Integer :client_id
    Integer :file_id
end

db.create_table(:files_invoices) do
    Integer :invoice_id
    Integer :file_id
end

问题是,如何正确设置模型中的关系,以便每个clientinvoice可以有一个或多个相关的files

可以使用many_to_manyhas_many :through关联完成此操作,但是,这似乎不是正确的方法,因为给定的file可以仅属于一个customerinvoice,而不属于多个。

我也可以使用多态,但documentation discourages this approach

  

Sequel不鼓励使用多态关联,即   默认情况下不支持它们的原因。所有多态关联   可以通过使用附加表和/或列使其成为非多态的   而不是将包含关联类名的列作为   字符串。

     

多态关联破坏了参照完整性   比非多态关联明显更复杂,所以他们的   除非您坚持使用现有设计,否则不建议使用   使用它们。

更正确的关联是one_to_many_throughmany_to_one_through,但我找不到正确的方法来执行此操作。是否有一种香草的Sequel方法来实现这一目标,还是有一个提供此功能的模型插件?

1 个答案:

答案 0 :(得分:0)

使用您当前的架构,您只想对文件使用many_to_many关联:

title

要确保每个文件只能有一个客户端/发票,您可以将file_id作为clients_files和files_invoices的主键(一个普通的唯一约束/索引也可以)。然后你可以使用one_through_one:

INDEX(title, emp_no)

请注意,这仍然允许将文件与客户端和发票相关联。如果要防止这种情况,则需要更改架构。您可以将client_id和invoice_id外键移动到files表(或使用带有两个键的单个连接表),并使用检查约束来检查是否只设置了其中一个。

请注意,避免多态键(除了复杂性)的主要原因是它允许数据库强制引用完整性。使用当前的连接表,您不会创建外键,只是整数字段,因此您不会强制执行参照完整性。