我知道有很多关于这些内容的文档,但我似乎无法将我脑海中的关联转换为rails,即使设置看起来很简单。
我们从用户模型开始。每个用户可能拥有多个地址,电话号码和(房地产)seller_listings,而每个卖家列表都有一个用户,地址和电话号码。
现在,这就是我所拥有的:
class User < ActiveRecord::Base
has_many :seller_listings
has_many :phone_numbers
has_many :addresses
class SellerListing < ActiveRecord::Base
belongs_to :user
belongs_to :address
belongs_to :phone_number
class Address < ActiveRecord::Base
belongs_to :user
class PhoneNumber < ActiveRecord::Base
belongs_to :user
mysql> desc seller_listings;
+--------------------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user_id | int(11) | NO | | NULL | |
| address_id | int(11) | NO | | NULL | |
| phone_number_id | int(11) | NO | | NULL | |
|...snip...
mysql> desc addresses;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user_id | int(11) | NO | | NULL | |
| address1 | varchar(255) | NO | | NULL | |
|...snip...
mysql> desc phone_numbers;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user_id | int(11) | NO | | NULL | |
|...snip...
这种各种作品,但我觉得这是错的。在为新用户创建seller_listing时,我必须创建然后构建地址和电话号码,如下所示:
# User
if user = User.find_by_email(args['user']['email'])
user.update_attributes(:first_name => args['user']['first_name'],
:last_name => args['user']['last_name'])
else
new_password = User.generate_new_password
user = User.create(:password => new_password, :confirmation_password => new_password,
:email => args['user']['email'],
:first_name => args['user']['first_name'],
:last_name => args['user']['last_name'])
end
# Address
addr = user.addresses.find_or_create_by_address1_and_zip(args['address']['address1'], args['address']['zip'])
# Phone Number
phone = user.phone_numbers.find_or_create_by_number(args['phone_number']['number'])
user.save!
然后,当我收到用户后,我可以创建卖家列表:
SellerListing.create!(:user_id => user.id, :address_id => addr.id, :phone_number_id => phone.id)
就像我说的,这一切都有效,但我试图通过在seller_listing中使用accepts_nested_attributes_for:user,:address,:phone_number来清理代码,但这不起作用我假设因为seller_listing目前有belongs_to:user,:地址和:phone_number。
所以,我显然已经破坏了模型关联,并且可以使用一些帮助,如果有人有一些建议。
[经过深思熟虑后编辑] 解决方案是将has_one:user,:address和:phone_number添加到卖家列表中,然后在创建时执行以下操作:
ruby-1.8.7-p302 > sl=SellerListing.new
ruby-1.8.7-p302 > sl.user.build("last_name"=>"Bar", "first_name"=>"Foo", "email"=>"foobar@example.com")
<repeat for address and phone number>
答案 0 :(得分:1)
我的答案是多态关联。以下是关于我所使用的修复的笔记:
用户有许多卖家列表,地址和电话号码 卖家列表有一个地址和一个电话号码
数据库更改:
地址表
add_column :address_context_id, :integer, :null => false
add_column :address_context_type, :string, :null => false
电话号码表
add_column :phone_number_context_id, :integer, :null => false
add_column :phone_number_context_type, :string, :null => false
填充新的cols / backfil
模型关联
地址
belongs_to :address_context, :polymorphic => true
电话号码
belongs_to :phone_number_context, :polymorphic => true
用户
has_many :addresses, :as => :address_context
has_many :phone_numbers, :as => :phone_number_context
卖家清单
has_one :address, :as => :address_context
has_one :phone_number, :as => :phone_number_context
有用的网站
http://media.railscasts.com/videos/154_polymorphic_association.mov
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
http://blog.opensteam.net/past/2008/11/26/polymorphic_controller_nested_routes_polymorphic