2010-02-12 3 views
18

J'ai un utilisateur et un modèle de profil. Un utilisateur peut avoir plusieurs profils. J'ai besoin d'accéder à une seule information de la section des profils (à savoir le numéro de téléphone) dans mon modèle d'utilisateur au cours du processus de création de l'utilisateur. Par conséquent, j'essaie de le faire à travers attr_accessible. Mon user.rb ressemble à ceci.Formes imbriquées dans les rails - accès à l'attribut dans la relation has_many

has_many :profiles 
attr_accessible :handle, :email, :password, :profile_mobile_number 
attr_accessor : :profile_mobile_number 

Le problème que je suis face est que lorsque je tente d'appeler la méthode getter profile_mobile_number dans un procédé user.rb (la méthode est privée, mais je pense qu'il n'a pas d'importance), je m obtenant une valeur nulle. J'utilise ce qui suit dans mes utilisateurs/formulaire new.html.erb

Ma question est quelle est la bonne façon de le faire? Dois-je utiliser <% f.fields_for :profile do |ff| -%> ou <% f.fields_for :profiles do |ff| -%> (remarquez que le second est pluriel). Quand j'utilise le pluriel: profils, je ne vois même pas les champs sur le formulaire. Qu'est-ce que j'oublie ici? Et quel est le temps qui doit être utilisé dans le modèle user.rb? : profile_phone_number ou: profiles_phone_number? Merci.

+0

Comme je l'ai dit, j'utilisais f.fields_for: les profils et les champs du formulaire ne s'affichaient pas. Il s'avère que j'ai dû ajouter @ user.profiles.build dans le contrôleur. Mais maintenant je ne suis pas capable d'avoir à la fois attr_accessible et accept_nested_attributes_for dans user.rb. Le premier remplace le dernier. Mais je veux avoir attr_accesible pour les attributs du modèle utilisateur sans restreindre l'accès aux attributs du modèle de profil. Des idées? Merci. –

Répondre

16

Vous pouvez faire quelque chose comme ce qui suit:

<% form_for @user, :url => { :action => "update" } do |user_form| %> 
    ... 
    <% user_form.fields_for :profiles do |profiles_fields| %> 
    Phone Number: <%= profiles_fields.text_field :profile_mobile_number %> 
    <% end %> 
<% end %> 

Mais puisque vous avez déjà une association, alors peut aussi bien utiliser « accepts_nested_attributes_for »

+6

Il vaut la peine de mentionner que cela itére sur les objets associés qui existent déjà. Il ne crée cependant aucun nouvel enregistrement vide à remplir. Utilisez un assistant pour celui qui ajoute un nouvel enregistrement si aucun n'est dans l'association, par exemple "def setup_profiles (utilisateur); user.profiles.build si user.profiles.blank? ||! User.profiles.map (&: new_record?) .any ?; user; end ", puis en utilisant" form_for setup_profiles (@user) do ... " – hurikhan77

+1

@ Le commentaire de hurikhan77 est crucial! Vous devez construire un nouvel objet si aucun objet associé n'existe, sinon rien n'apparaît dans votre formulaire! – agmin

0

Vous pouvez utiliser « accepts_nested_attributes_for » pour ce faire; mais il y a un petit truc dans les formes:

Vous devez utiliser le singulier, et appeler fields_for pour chaque profil, comme ceci:

<% form_for @user do |f| -%> 
<% @user.profiles.each do %> 
<% f.fields_for :profile_attributes, profile do |ff| -%> 
<% end %> 

avis qui : profile_attributes, au lieu de simplement : profil .

+3

Si une association * appartient à polymorphic *, vous devez définir une méthode * build_profile * dans votre modèle User. – nanda

Questions connexes