我正在将现有的perl gtk应用转换为ROR应用
我有一个3路habtm关联模型。
class CustomerMaster < ActiveRecord::Base
has_and_belongs_to_many :address_master, :join_table => "customer_phone_addres"
has_and_belongs_to_many :phone_master, :join_table => "customer_phone_address"
class AddressMaster < ActiveRecord::Base
has_and_belongs_to_many :customer_master, :join_table => "customer_phone_addres"
has_and_belongs_to_many :phone_master, :join_table => "customer_phone_addres"
class PhoneMaster < ActiveRecord::Base
has_and_belongs_to_many :customer_master, :join_table => "customer_phone_addres"
has_and_belongs_to_many :address_master, :join_table => "customer_phone_addres"
联接表具有以下架构
CREATE TABLE customer_phone_address
(
id bigserial NOT NULL,
customer_master_id bigint,
phone_master_id bigint,
address_master_id bigint,
CONSTRAINT customer_phone_address_pkey PRIMARY KEY (id),
CONSTRAINT address FOREIGN KEY (address_master_id)
REFERENCES address_master (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT customer FOREIGN KEY (customer_master_id)
REFERENCES customer_master (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT phone FOREIGN KEY (phone_master_id)
REFERENCES phone_master (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT uniq_cust_phone_address UNIQUE (customer_master_id, phone_master_id, address_master_id)
)
我为customer_master #new创建了一个嵌套表单,其中包含address_master和phone_master的输入
最初对于perl gtk应用程序,在join_table中只为客户,地址和电话的每个条目创建一个条目
id|customer_master_id|phone_master_id|address_master_id
186767|182774|500773|210683
然而,使用上述关系模型,在ROR的情况下我得到两个条目
id|customer_master_id|phone_master_id|address_master_id
186769|182810|500775|nil|
186770|182810|nil|211935|
我需要保持对perl gtk应用程序的向后兼容性。 如何在联接表中输入单个条目而不是两个条目?
我认为这个问题类似于 https://stackoverflow.com/questions/5507150/custom-join-3-tables-usage-in-rails-2-3-8
答案 0 :(得分:4)
假设您使用的是Rails 3。
当您的连接表只有2个外键时,您应该使用habtm
。对于大多数情况,has_many :through
会更灵活。
在您的情况下,您应该为连接表创建一个模型。首先,您应该禁用旧数据库模式的复数。 (我以为你已经这样做了)。
# In config/application.rb
config.active_record.pluralize_table_names = false
按惯例创建一个连接表,即CustomerPhoneAddress
(我将给它一个更有意义的名称):
# customer_phone_address.rb
class CustomerPhoneAddress < ActiveRecord::Base
belongs_to :address_master
belongs_to :customer_master
belongs_to :phone_master
end
最后,将您的模型与has_many
和has_many :through
:
# address_master.rb
class AddressMaster < ActiveRecord::Base
has_many :customer_phone_addresses
has_many :customer_masters, :through => :customer_phone_addresses
has_many :phone_masters, :through => :customer_phone_addresses
end
# customer_master.rb
class CustomerMaster < ActiveRecord::Base
has_many :customer_phone_addresses
has_many :address_masters, :through => :customer_phone_addresses
has_many :phone_masters, :through => :customer_phone_addresses
end
# phone_master.rb
class PhoneMaster < ActiveRecord::Base
has_many :customer_phone_addresses
has_many :customer_masters, :through => :customer_phone_addresses
has_many :phone_masters, :through => :customer_phone_addresses
end
我测试了代码并且它运行良好。要创建关联:
CustomerPhoneAddress.create(
:phone_master => PhoneMaster.first,
:address_master => AddressMaster.first,
:customer_master => CustomerMaster.first)
查询关联:
IRB> a = AddressMaster.first
=> #<AddressMaster id: 1, created_at: "2011-12-07 15:23:07", updated_at: "2011-12-07 15:23:07">
IRB> a.customer_masters
=> [#<CustomerMaster id: 1, created_at: "2011-12-07 15:23:15", updated_at: "2011-12-07 15:23:15">]
IRB> a.phone_masters
=> [#<PhoneMaster id: 1, created_at: "2011-12-07 15:23:19", updated_at: "2011-12-07 15:23:19">]
IRB> a.customer_phone_addresses
=> [#<CustomerPhoneAddress id: 1, address_master_id: 1, customer_master_id: 1, phone_master_id: 1, created_at: "2011-12-07 15:24:01", updated_at: "2011-12-07 15:24:01">]