Нужна помощь с ассоциацией моделей рельсов - PullRequest
1 голос
/ 09 апреля 2011

Я знаю, что есть много документации по этому материалу, но я не могу преобразовать ассоциации в моей голове в рельсы, даже если установка кажется довольно простой.

Мы начнем с пользователямодель.У каждого пользователя есть потенциальные адреса, номера телефонов и (недвижимость) списка продавцов, в то время как у каждого продавца есть один пользователь, адрес и номер телефона.

Сейчас у меня есть вот что:

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

Это все виды работ, но я чувствую, что это неправильно.При создании списка продавцов для нового пользователя я должен создать, а затем построить адрес и номер телефона примерно так:

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

Как я уже сказал, это все вроде работает, но я пытаюсь очистить код с помощью accepts_nested_attributes_for: user,: address,: phone_number в seller_listing, но это не работает, я полагаю, потому что seller_listing в настоящее время имеет own_to:user,: address and: 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 Ответ

1 голос
/ 11 апреля 2011

Ответом для меня была полиморфная ассоциация. Вот мои заметки относительно исправления, которое я использовал:

Полиморфные ассоциации

У пользователя есть много продавцов списки, адреса и телефоны Листинг продавца имеет один адрес и один номер телефона

Изменения в базе данных:

  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

Модельные ассоциации

  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
    

Полезные сайты

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

...