2010-07-24 4 views
3

В последнее время у меня много вопросов, но благодаря этому удивительному сообществу я учу тонну.Полиморфизм и формы в Ruby on Rails

Раньше у меня была вся необходимая помощь с полиморфными ассоциациями, и теперь у меня есть вопрос о решении форм с полиморфными моделями. Например, у меня есть Phoneable и User, поэтому, когда я создаю свою форму для регистрации пользователя, я хочу иметь возможность назначить пользователю несколько телефонных номеров (например, cell, work, home).

class User < ActiveRecord::Base 
    has_many :phones, :as => :phoneable 
end 

class Phone < ActiveRecord::Base 
    belongs_to :phoneable, :polymorphic => true 
end 

class CreateUsers < ActiveRecord::Migration 
    t.column :name, :string 
    t.references :phoneable, :polymorphic => true 
end 

class CreatePhones < ActiveRecord::Migration 
    t.column :area_code, :integer 
    t.column :number, :integer 
    t.column :type, :string 
    t.references :phoneable, :polymorphic => true 
end 

Теперь, когда я создаю свою форму, я смущаюсь. Обычно я бы сделал следующее:

- form_for :user, :html => {:multipart => true} do |form| 
    %fieldset 
    %label{:for => "name"} Name: 
    = form.text_field :name 
    ##now how do I go about adding a phone number? 
    ##typically I'd do this: 
    ##%label{:for => "phone"} Phone: 
    ##= form.text_field :phone 

Используя полиморфизм, я бы просто приблизился таким же образом, но использовал fields_for?

- user_form.fields_for :phone do |phone| %> 
    %label{for => "area_code"} Area Code: 
    = phone.text_field :area_code 
    %label{for => "number"} Number: 
    = phone.text_field :number 

Это правильный подход в этом случае?

ответ

7

Прежде чем идти дальше, я заметил одну проблему - вам не нужен t.references с стороной has_many. Так что вам это не нужно в модели create_user. Что это делает, он создает столбцы phonable_id и phoneable_type, вам это нужно только в полиморфной модели.

Вы направляетесь по правильному пути с помощью подхода fields_for. Но чтобы получить эту работу, вам нужно указать модели, как обрабатывать эти поля. Вы делаете это с помощью метода класса accepts_nested_attributes_for.

class User < ActiveRecord::Base 
    has_many :phones, :as => :phoneable 

    accepts_nested_attributes_for :phones 
end 

и одна незначительная вещь, вам нужно будет иметь fields_for точку в точного имени объединения

- form_for @user do |user_form| 
    - user_form.fields_for :phones do |phone| 

Вместо

- form_for @user do |user_form| 
    - user_form.fields_for :phone do |phone| 

и убедитесь, что вы удалите ваш бродячий %> erb tag :)

Подробнее о accepts_nested_attributes_for: http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

Надеюсь, это поможет!

+0

Отличный ответ и огромное спасибо за помощь! Это именно то, что я искал. Просто, чтобы уточнить, прежде чем я столкнулся с какими-либо проблемами. В моих createUsers мне не нужно включать столбец для телефонов? т.е.: t.column: phone,: phoneable Или что-то в этом роде? –

+0

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

+0

Сладкий. Еще раз спасибо! –

Смежные вопросы