Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 是否可以在Sequel ORM中使用“一到多”关联?_Ruby_Orm_Sequel - Fatal编程技术网

Ruby 是否可以在Sequel ORM中使用“一到多”关联?

Ruby 是否可以在Sequel ORM中使用“一到多”关联?,ruby,orm,sequel,Ruby,Orm,Sequel,我有一个案例,其中一个模型与另外两个模型相关。我正在尝试正确设置这3个模型之间的模型关系 一个简化的例子。。。前两个表是客户和发票: db.create_table(:clients) do primary_key :id String :name end db.create_table(:invoices) do primary_key :id String :description Integer :balance end db.create_ta

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

一个简化的例子。。。前两个表是
客户
发票

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

db.create_table(:invoices) do
    primary_key :id
    String :description
    Integer :balance
end
db.create_table(:files) do
    primary_key :id
    String :name
    String :path
    String :type # [image, pdf, word, excel]
end
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
第三个表称为
文件
,包含与
客户
发票
相关的文件记录:

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

db.create_table(:invoices) do
    primary_key :id
    String :description
    Integer :balance
end
db.create_table(:files) do
    primary_key :id
    String :name
    String :path
    String :type # [image, pdf, word, excel]
end
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
有两个joiner表可将
文件
连接到
客户
发票

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

db.create_table(:invoices) do
    primary_key :id
    String :description
    Integer :balance
end
db.create_table(:files) do
    primary_key :id
    String :name
    String :path
    String :type # [image, pdf, word, excel]
end
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
问题是,如何正确设置模型中的关系,以便每个
客户机
发票
可以有一个或多个相关的
文件

我可以使用
many to_many
has_many:through
关联来实现这一点,但是,这似乎不是正确的方法,因为给定的
文件
只能属于一个
客户
发票
,而不是属于多个客户

我也可以使用多态性来实现这一点,但是:

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

多态关联破坏了引用完整性,并且 明显比非多态性关联更复杂,因此 除非您坚持使用现有设计,否则不建议使用 这就使用了它们


更正确的关联应该是
one-to-one-to-one-to-one-to-to-one-to-to-one-to-to-one-to-to-one-to-to-one-to-to-one-to-to-one-to-to-to-to-one-to-to。是否有一个普通的续集方式来实现这一点,或者有一个模型插件来提供这一功能

对于当前模式,您只需要使用多对多的文件关联:

Client.many_to_many :files
Invoice.many_to_many :files
为了确保每个文件只能有一个客户机/发票,您可以将file_id设置为客户机文件和发票文件的主键(一个简单的唯一约束/索引也可以使用)。然后您可以使用一个到一个:

File.one_through_one :client
File.one_through_one :invoice
请注意,这仍然允许将文件与客户机和发票关联。如果要防止这种情况发生,需要更改模式。您可以将client_id和invoice_id外键移动到files表(或者使用一个包含两个键的联接表),并使用一个检查约束来检查是否只设置了其中一个键


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

Jeremy,这就是我最后所做的(使用复合主键的多对多)。不幸的是,无法更改现有模式。顺便说一句,我必须感谢您创建了一个宝石中的宝石,但更重要的是,感谢您为您的产品付出的时间、精力和承诺。你总是能很快地回答所有与续集相关的问题(这是你第三次亲自回答我的问题,之前在邮件列表中也有几次)。我只是想让你们知道,你们的支持和承诺并不是不被认可的,我认识的许多开发人员(包括我自己)都对Sequel而不是ActiveRecord或DataMapper发誓。继续努力,我们都为此感谢你!