我正在为发票/客户/合同数据库编写相当简单的Web界面。 我希望我的模型具有以下结构:
class Invoice < ActiveRecord::Base
set_table_name 't10_invoices'
set_primary_key 'id_invoice'
has_one :client
end
class Client < ActiveRecord::Base
set_table_name 't20_clients'
set_primary_key 'id_client'
has_many :invoices
end
问题是我有以下数据库结构:
Tables:
t10_invoices:
id_invoice - primary_key
id_contract - foreign_key
t12_contracts:
id_contract - primary_key
t15_contracts_clients
id_client - foreign_key
id_contract - foreign_key
t20_clients
id_client - primary_key
t20_clients
和t12_contracts
到t15_contracts_clients
之间存在1-1关系
并且t20_clients
和t10_invoices
之间存在1-n关系。
:foreign_key
和:association_foreign_key
之间的区别是什么?
问题是我无法修改数据库的结构,而且在重新定义表名,外键,join_foreign_keys等时我完全迷失了...
我想用一种简单的方法以正常的Rails方式查找发票的客户Invoice.find(:first).client
我将不胜感激任何建议和帮助。
答案 0 :(得分:2)
创建ContractClient
连接模型以对应t15_contracts_clients表。这指定了表名,并对2个外键使用belongs_to
关联:
class ContractClient < ActiveRecord::Base
set_table_name 't15_contracts_clients'
belongs_to :client, :foreign_key => :id_client
belongs_to :contract, :foreign_key => :id_contract
end
指定Client
的表和主键:
class Client < ActiveRecord::Base
set_table_name 't20_clients'
set_primary_key 'id_client'
end
在发票上使用belongs_to :contract_client
,然后在has_one :through
上通过ContractClient
关联客户:
class Invoice < ActiveRecord::Base
set_table_name 't10_invoices'
set_primary_key 'id_invoice'
belongs_to :contract_client, :foreign_key => :id_contract
has_one :client, :through => :contract_client
end
Invoice.find(:first).client
应该按预期运行。
答案 1 :(得分:2)
你在模型中有几个奇怪的地方。它不是以客户has_one
合同的方式设置的。它在中间有一个连接表,允许每个客户端签订多个合同。由于您无法更改表,因此最好只强制执行代码中的任何关系。由于该表显然没有主键,因此您可能需要使用has_and_belongs_to_many
。在该关系类型中,:association_foreign_key
用于“其他”类,:foreign_key
用于您所在的类。
class Invoice < ActiveRecord::Base
set_table_name 't10_invoices'
set_primary_key 'id_invoice'
belongs_to :contract, :foreign_key => 'id_contract'
has_one :client, :through => :contract
end
class Contract
set_table_name 't12_contracts'
set_primary_key 'id_contract'
has_and_belongs_to_many :clients,
:join_table => 't15_contracts_clients'
:foreign_key => 'id_contract',
:association_foreign_key => 'id_client'
has_many :invoices, :foreign_key => 'id_contract'
end
class Client < ActiveRecord::Base
set_table_name 't20_clients'
set_primary_key 'id_client'
has_and_belongs_to_many :clients,
:join_table => 't15_contracts_clients'
:foreign_key => 'id_client',
:association_foreign_key => 'id_contract'
has_many :invoices, :through => :contracts
end
然后你需要调用
Invoice.find(:first).client
答案 2 :(得分:1)
您是否考虑过创建数据库view?