复杂连接Rails中的旧表

时间:2009-12-15 16:43:04

标签: ruby-on-rails ruby activerecord

我正在为发票/客户/合同数据库编写相当简单的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_clientst12_contractst15_contracts_clients之间存在1-1关系 并且t20_clientst10_invoices之间存在1-n关系。

:foreign_key:association_foreign_key之间的区别是什么?

问题是我无法修改数据库的结构,而且在重新定义表名,外键,join_foreign_keys等时我完全迷失了... 我想用一种简单的方法以正常的Rails方式查找发票的客户Invoice.find(:first).client

我将不胜感激任何建议和帮助。

3 个答案:

答案 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

相关问题