需要帮助rails model association

时间:2011-04-09 15:19:24

标签: ruby-on-rails associations

我知道有很多关于这些内容的文档,但我似乎无法将我脑海中的关联转换为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>

1 个答案:

答案 0 :(得分:1)

我的答案是多态关联。以下是关于我所使用的修复的笔记:

多态关联

用户有许多卖家列表,地址和电话号码 卖家列表有一个地址和一个电话号码

数据库更改:

  1. 地址表

    add_column :address_context_id, :integer, :null => false
    add_column :address_context_type, :string, :null => false
    
  2. 电话号码表

    add_column :phone_number_context_id, :integer, :null => false
    add_column :phone_number_context_type, :string, :null => false
    
  3. 填充新的cols / backfil

  4. 模型关联

    1. 地址

      belongs_to :address_context, :polymorphic => true
      
    2. 电话号码

      belongs_to :phone_number_context, :polymorphic => true
      
    3. 用户

      has_many :addresses, :as => :address_context
      has_many :phone_numbers, :as => :phone_number_context
      
    4. 卖家清单

      has_one :address, :as => :address_context
      has_one :phone_number, :as => :phone_number_context
      
    5. 有用的网站

      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