2010-07-24 29 views
3

J'ai été plein de questions ces derniers temps, mais grâce à cette communauté géniale, j'apprends énormément.Polymorphisme et formes dans Ruby on Rails

J'ai eu toute l'aide dont j'avais besoin avec les associations polymorphes plus tôt et maintenant j'ai une question sur la façon d'aborder les formes avec des modèles polymorphes. Par exemple, j'ai Phoneable et User, donc quand je crée mon formulaire pour enregistrer un utilisateur, je veux être en mesure d'attribuer quelques numéros de téléphone à l'utilisateur (c'est-à-dire: cellule, travail, maison).

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 

Maintenant, lorsque je crée mon formulaire, je suis confus. Normalement, je ferais ce qui suit:

- 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 

polymorphisme En utilisant, ce que j'approche de la même façon, mais utiliser 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 

Est-ce la bonne approche dans ce cas?

Répondre

7

Avant d'aller plus loin, j'ai remarqué un problème - vous n'avez pas besoin du t.references avec le côté has_many de l'association. Donc, vous n'en avez pas besoin dans le modèle create_user. Qu'est-ce que cela fait, c'est créer les phonable_id et les colonnes phoneable_type, vous en avez seulement besoin dans le modèle polymorphe.

Vous suivez le chemin correct avec l'approche fields_for. Mais pour que cela fonctionne, vous devez indiquer au modèle comment gérer ces champs. Vous faites cela avec la méthode de classe accepts_nested_attributes_for.

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

    accepts_nested_attributes_for :phones 
end 

et une chose mineure, vous aurez besoin d'avoir le point fields_for au nom exact de l'association

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

Au lieu de

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

et assurez-vous retirer votre égaré %> erb tag :)

Plus d'informations sur accepts_nested_attributes_for: http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

J'espère que cela aide!

+0

Grande réponse et un grand merci pour l'aide! C'est exactement ce que je cherchais. Juste pour clarifier cependant, avant que je rencontre des problèmes. Dans mes createUsers, je n'ai pas besoin d'inclure une colonne pour les téléphones? c'est-à-dire: t.colonne: téléphone,: phoneable Ou quelque chose du genre? –

+0

Non, c'est comme n'importe quelle autre relation has_many, elle utilise les clés étrangères de la table polymorphique dans la jointure. –

+0

Sweet. Merci encore! –