2012-05-08 17 views
15

Ecco il modello di genitore:Come mantenere l'ordine per gli attributi nidificati quando si utilizza accepts_nested_attributes_for in un'applicazione Rails

class TypeWell < ActiveRecord::Base 
    ... 

    has_many :type_well_phases, :dependent => :destroy 
    accepts_nested_attributes_for :type_well_phases, :reject_if => lambda { |a| a[:phase_id].blank? }, :allow_destroy => true 

    ... 
end 

Ecco il modello nidificato:

class TypeWellPhase < ActiveRecord::Base 

    belongs_to :type_well 
    belongs_to :phase 

end 

Qui è il modello di fase:

class Phase < ActiveRecord::Base 
    ... 
    has_many :type_well_phases 
    ... 
end 

aggiungo record nidificati in tabella figlio (TypeWellPhases) copiando tutti i record fro M Il mio fasi (modello Phase) tavolo di controllo del modello genitore come illustrato di seguito:

class TypeWellsController < ResourceController 
    ... 
    def new 
    @new_heading = "New Type Well - Computed" 
    @type_well = TypeWell.new 
    initialize_phase_fields 
    end 

    private 

    def initialize_phase_fields 
    Phase.order("id").all.each do |p| 
     type_well_phase    = @type_well.type_well_phases.build 
     type_well_phase.phase_id  = p.id 
     type_well_phase.gw_heat_value = p.gw_heat_value 
    end 
    end 
    ... 
end 

Lo faccio perché voglio mantenere un ordine specifico dai campi per bambini che vengono aggiunti. La parte del codice Phase.order ("id") è per questo poiché la tabella delle fasi contiene questi record in un ordine specifico.

Dopo questo, io uso le simple_form_for e simple_fields_for aiutanti come illustrato di seguito nella mia forma parziale:

= simple_form_for @type_well do |f| 
    ... 
    #type_well_phases 
     = f.simple_fields_for :type_well_phases do |type_well_phase| 
     = render "type_well_phase_fields", :f => type_well_phase 

Tutto funziona come desiderato; La maggior parte delle volte. Tuttavia, a volte l'ordine delle righe figlio nel modulo viene incasinato dopo che è stato salvato. L'ordine è importante in questa applicazione ed è per questo che faccio esplicitamente questo ordine nel metodo privato nel controller.

Sto usando la gemma "bozzolo" per aggiungere la rimozione di record figlio. Non sono sicuro del motivo per cui a volte questo ordine viene incasinato.

Mi dispiace per un post così lungo, ma volevo fornire tutti i dettagli pertinenti in anticipo.

Apprezzare qualsiasi suggerimento.

Bharat

risposta

38

Ti spiegherò in un modo più generico. Dire, si dispone di prodotti e sugli ordini modelli:

= form_for @product do |f| 
    ... 
    = f.fields_for :orders do |order_fields| 
     = order_fields.text_field :name 

Se volete che i vostri ordini ad essere ordinati per nome poi basta ordinarli :)

Invece di:

= f.fields_for :orders do |order_fields| 

put:

Come si vede, la variabile f è un parametro del blocco di form_for ha il metodo object. È il tuo @product, quindi puoi recuperare i suoi ordini tramite .orders e quindi applicare l'ordinamento necessario tramite .order(:name) (mi dispiace per questa piccola confusione: ordine/ordini).

La chiave della soluzione è che è possibile passare ordini ordinati come secondo parametro per fields_for.

P.S. L'utilizzo della gemma simple_form non influisce sulla mia soluzione. Funzionerà se aggiungerai 'simple_' agli helper. Volevo solo che la mia risposta fosse più utile per gli altri e non troppo legata al compito.

+0

Grazie per la vostra spiegazione eccellente. Ho solo una domanda successiva: come lo sapevi? Ho letto e riletto la documentazione e non potevo nemmeno pensarci. In altre parole, insegnami a pescare :) – Bharat

+0

Non c'è magia, @Bharat. È nella documentazione ufficiale in bella vista. Vai a http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-fields_for e scorri fino alle parole "O una collezione da utilizzare". – jdoe

+0

Mi ha aiutato a risolvere la mia domanda http://stackoverflow.com/questions/13699285/how-to-make-text-fields-for-nested-attributes-in-rails-for-selected-records –

1

Se si utilizza Rails 2.3.14 o superiore è necessario utilizzare:

f.fields_for :orders, f.object.orders.all(:order => :name) do |order_fields| 
Problemi correlati