2012-05-08 10 views
15

Aquí está el modelo padre:Cómo mantener el orden de los atributos anidados cuando se utiliza accepts_nested_attributes_for en una aplicación 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 

Aquí es el modelo anidado:

class TypeWellPhase < ActiveRecord::Base 

    belongs_to :type_well 
    belongs_to :phase 

end 

Aquí es el modelo de fase:

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

Agregue registros anidados en la tabla secundaria (TypeWellPhases) copiando TODOS los registros de soy mi fases (Fase modelo) mesa en el controlador del modelo de matriz como se muestra a continuación:

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 

hago esto porque quiero mantener un orden específico por los campos de los niños que se agregan. La parte del código Phase.order ("id") es para eso dado que la tabla de fases tiene estos registros en un orden específico.

Después de esto yo uso el simple_form_for y simple_fields_for ayudantes como se muestra a continuación en forma parcial mi:

= 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 

Todo funciona como se desea; La mayoría de las veces. Sin embargo, a veces el orden de las filas de Child en el formulario se descompone después de que se ha guardado. El orden es importante en esta aplicación y es por eso que explícitamente hago este orden en el método privado en el controlador.

Estoy usando la gema "capullo" para agregar la eliminación de registros secundarios. No estoy seguro de por qué esta orden se arruina a veces.

Lo siento por una publicación tan larga, pero quería proporcionar todos los detalles pertinentes por adelantado.

Aprecie cualquier apuntador.

Bharat

Respuesta

38

Te explicaré de una manera más genérica. Por ejemplo, que tiene un producto y del Orden modelos:

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

Si desea que sus órdenes sean ordenados por nombre, entonces sólo una especie ellos :)

En lugar de:

= f.fields_for :orders do |order_fields| 

puesto:

= f.fields_for :orders, f.object.orders.order(:name) do |order_fields| 

Como ve, la variable f que es un parámetro del bloque de form_for tiene el método object. Es su @producto, por lo que puede obtener sus pedidos a través del .orders y luego aplicar la clasificación necesaria a través del .order(:name) (disculpe esta pequeña confusión: orden/pedidos).

La clave para su solución es que puede pasar órdenes clasificadas como el segundo parámetro para fields_for.

P.S. Tu uso de la gema simple_form no afecta mi solución. Funcionará si agrega 'simple_' a los ayudantes. Solo quería que mi respuesta fuera más útil para los demás y no demasiado relacionada con las tareas.

+0

Gracias por su excelente explicación. Solo tengo una pregunta de seguimiento: ¿cómo supiste esto? Leí y volví a leer la documentación y ni siquiera pude pensar en esto. En otras palabras, enséñame a pescar :) – Bharat

+0

No hay magia, @Bharat. Está en la documentación oficial a la vista. Vaya a http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-fields_for y desplácese hacia abajo hasta las palabras "O una colección que se utilizará". – jdoe

+0

me ayudó a resolver mi pregunta su http://stackoverflow.com/questions/13699285/how-to-make-text-fields-for-nested-attributes-in-rails-for-selected-records –

1

Si está utilizando rieles 2.3.14 o más que tienen que usar:

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