2010-02-12 12 views
18

Ho un utente e un modello di profilo. Un utente può avere molti profili. Ho bisogno di accedere a una sola informazione dalla sezione profili (cioè il numero di telefono) nel mio modello utente durante il processo di creazione dell'utente. Quindi sto cercando di farlo attraverso attr_accessible. Il mio user.rb ha questo aspetto.Moduli annidati in rotaia - accesso all'attributo in has_many relation

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

Il problema che sto affrontando è che quando provo a chiamare il metodo getter profile_mobile_number in un metodo in user.rb (il metodo è privato, anche se penso che non importa), I' m ottenendo un valore nullo. Io uso il seguente nella mia forma utenti/new.html.erb

La mia domanda è che cosa è il modo giusto per fare questo? Dovrei usare <% f.fields_for :profile do |ff| -%> o <% f.fields_for :profiles do |ff| -%> (notare che il secondo è plurale). Quando uso il plurale: profili, non vedo nemmeno i campi sul modulo. Cosa mi manca qui? E qual è il tempo che deve essere usato nel modello user.rb? : profile_phone_number o: profiles_phone_number? Grazie.

+0

Come ho detto, stavo usando f.fields_for: profili e i campi nel modulo non venivano visualizzati. Risulta che ho dovuto aggiungere @ user.profiles.build nel controller. Ma ora non sono in grado di avere sia attr_accessible che accept_nested_attributes_for in user.rb. Il primo ha la precedenza su quest'ultimo. Ma voglio avere attr_accesible per gli attributi del modello utente mentre NON limita l'accesso agli attributi del modello del profilo. Qualche idea? Grazie. –

risposta

16

Si potrebbe fare qualcosa di simile al seguente:

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

Ma dal momento che si dispone già di un'associazione, quindi potrebbe anche usare 'accepts_nested_attributes_for'

+6

Vale la pena ricordare che questo itera sugli oggetti associati già esistenti. Tuttavia, non crea nuovi record vuoti da riempire. Utilizzare un helper per quello che aggiunge un nuovo record se nessuno è nell'associazione, ad esempio "def setup_profiles (utente); user.profiles.build se user.profiles.blank? ||! User.profiles.map (&: new_record?) .any ?; user; end ", quindi utilizzando" form_for setup_profiles (@user) do ... " – hurikhan77

+1

il commento di @ hurikhan77 è fondamentale! Devi creare un nuovo oggetto se non ci sono oggetti associati, altrimenti non compare nulla nel tuo modulo! – agmin

0

si può usare 'accepts_nested_attributes_for' per fare questo; ma c'è un piccolo trucco in forme:

è necessario utilizzare il singolare, e chiamare fields_for per ogni profilo, in questo modo:

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

Si noti che è : profile_attributes, invece di solo : profilo .

+3

Se è un'associazione * belongs_to polymorphic *, è necessario definire un metodo * build_profile * nel proprio modello utente. – nanda