开发者

Need help with rails model association

开发者 https://www.devze.com 2023-02-23 00:41 出处:网络
I know there is alot of documentation out there on this stuff, but I can\'t seem to transform the associations in my head into rails even though the setup seems pretty simple.

I know there is alot of documentation out there on this stuff, but I can't seem to transform the associations in my head into rails even though the setup seems pretty simple.

We start with the user model. Each user potentially has_many addresses, phone numbers and (real estate)开发者_如何学编程 seller_listings while each seller_listing has one user, address and phone number.

Right now, this is what i have:

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...

This all kind of works but I feel like it is wrong. When creating a seller_listing for a new user, I have to create then build the address and phone number kinda like so:

# 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!

Then once I get the user, I can create the seller listing:

SellerListing.create!(:user_id => user.id, :address_id => addr.id, :phone_number_id => phone.id)

Like I said, this all kinda works but I am trying to clean up the code by using accepts_nested_attributes_for :user, :address, :phone_number in seller_listing but this doesn't work I assume because seller_listing currently has belongs_to :user, :address and :phone_number.

So, I have obviously botched the model association and could use some help if anybody out there has some suggestions.

[edited with after-thought] Is the solution to add has_one :user, :address and :phone_number to seller listing and then when creating do something like:

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>


The answer for me was polymorphic association. Here are my notes regarding the fix I employed:

Polymorphic Associations

User has many seller listings, addresses and phone numbers Seller Listing has one address and one phone number

Database Changes:

  1. Addresses Table

    add_column :address_context_id, :integer, :null => false
    add_column :address_context_type, :string, :null => false
    
  2. Phone Numbers Table

    add_column :phone_number_context_id, :integer, :null => false
    add_column :phone_number_context_type, :string, :null => false
    
  3. populate new cols/backfil

Model Associations

  1. Address

    belongs_to :address_context, :polymorphic => true
    
  2. Phone Number

    belongs_to :phone_number_context, :polymorphic => true
    
  3. User

    has_many :addresses, :as => :address_context
    has_many :phone_numbers, :as => :phone_number_context
    
  4. Seller Listing

    has_one :address, :as => :address_context
    has_one :phone_number, :as => :phone_number_context
    

Helpful sites

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

0

精彩评论

暂无评论...
验证码 换一张
取 消