2011-02-10 13 views
28

Sto usando Rails 3.0.3 con ruby ​​1.9.2p0.Rails 3 fields_for - l'ordinamento si perde

Nel mio profiles_controller (funzione di modifica) ho questa chiamata

@profile = Profile.find(params[:id]) 
@profile_items = @profile.profile_items.order("pos") 

per ottenere i @profile_items nell'ordine corretto, ordinato il "POS". Nella _form.html.erb ho il seguente

<% @profile_items.each do |pi| %> 
    <%= pi.pos %> | 
<% end %> 
<%= f.fields_for :profile_items do |f2| %> 
    <%= render 'profile_item_fields', :f => f2 %> 
<% end %> 

Le 3 prime linee sono codice di prova per mostrare che le @profile_items sono nell'ordine corretto. Ma quando sono renderizzati hanno perso l'ordine ordinato!

Ora ho una ricerca molto per una risposta e penso che questa deve essere una "trappola" comune a cadere in.

grato per qualsiasi aiuto ...

risposta

42

in base alla documentazione Rails per fields_for, è anche possibile specificare l'oggetto record dopo il nome del record.

Quindi qualcosa di simile a questo dovrebbe funzionare ...

<%= f.fields_for :profile_items, @profile_items do |f2| %> 
    <%= render 'profile_item_fields', :f => f2 %> 
<% end %> 
+20

Piccolo emendamento. Se si desidera mantenere ordinati i record, non farlo sull'associazione. Raccoglierà le cose dal database e spazzerà via le voci temporanee (come quelle con errori che non sono stati salvati). Quindi invece di '@ profile_items.order ('position')' fai qualcosa di simile a questo: '@ profile_items.sort_by (&: position)'. – Grocery

+1

Molto, molto, molto, molto, molto, molto meglio dell'utilizzo di un ambito predefinito. –

+0

... concorda con Grocery sul problema - ma i campi-per è implicito in base a 'accetta attributi nidificati per' - quindi non esiste @profile_items (utilizzando questo esempio) mai definito. Quindi, come ordinare la raccolta implicitamente generata? Ho trovato questa risposta qui: https://stackoverflow.com/questions/10505853/how-to-maintain-the-ordering-for-nested-attributes-when-using-accepts-nested-att – JosephK

17

questo può essere realizzato con un default_scope sul modello nidificato:

class YourModel < ActiveRecord::Base 
    belongs_to :other_model 
    default_scope { order(:name) } 
end 
+0

Grazie per questo. Stavo perdendo la volontà di continuare –

+0

Questa è la migliore risposta a tutto ciò che abbia mai visto. –

+0

Questa è una buona soluzione se vuoi _always_ vuoi ordinare questa classe allo stesso modo. Se alla fine si desidera ordinarlo in altri modi, ciò può rendere le cose molto complicate (è necessario escludere l'ambito predefinito ogni volta) e utilizzare un ordine manuale o più ambiti nominati è meglio. –