Подтвердить что ты не робот

Как поддерживать порядок вложенных атрибутов при использовании accepts_nested_attributes_for в приложении 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

Вот вложенная модель:

class TypeWellPhase < ActiveRecord::Base

  belongs_to :type_well
  belongs_to :phase

end

Вот фазовая модель:

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

Я добавляю вложенные записи в дочернюю таблицу (TypeWellPhases), копируя ВСЕ записи из моей фазы (Phase model) в родительском контроллере модели, как показано ниже:

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

Я делаю это, потому что я хочу поддерживать определенный порядок по добавляемым дочерним полям. Часть кода Phase.order( "id" ) предназначена для этого, поскольку таблица фаз имеет эти записи в определенном порядке.

После этого я использую simple_form_for и simple_fields_for помощников, как показано ниже в моей форме:

= 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

Все работает по своему желанию; в большинстве случаев. Однако иногда упорядочение дочерних строк в форме становится беспорядочным после того, как оно было сохранено. Порядок в этом приложении важен, поэтому я явно делаю это упорядочение в частном методе в контроллере.

Я использую драгоценный камень "кокона" для добавления удаленных дочерних записей. Я не уверен, почему этот порядок иногда перепутался.

Извините за такой длинный пост, но я хотел бы предоставить все соответствующие детали вперед.

Цените любые указатели.

Бхарат

4b9b3361

Ответ 1

Я объясню вам более общий характер. Скажем, у вас есть модели продукта и заказа:

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

Если вы хотите, чтобы ваши заказы сортировались по имени, просто выполните их сортировку:)

Вместо:

    = f.fields_for :orders do |order_fields|

ставить:

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

Как вы видите, переменная f, являющаяся параметром блока form_for, имеет метод object. Это ваш @product, так что вы можете получить его заказы через .orders, а затем применить необходимую сортировку через .order(:name) (извините за эту небольшую путаницу: order/orders).

Ключ к вашему решению, в котором вы можете передать отсортированные заказы как второй параметр для fields_for.

P.S. Ваше использование жемчуга simple_form не влияет на мое решение. Он будет работать, если вы добавите "simple_" к помощникам. Просто хотел, чтобы мой ответ был более полезным для других, и не слишком связан с задачей.

Ответ 2

Если вы используете Rails 2.3.14 или старше, вы должны использовать:

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