Как сохранить порядок для вложенных атрибутов при использовании accepts_nested_attributes_for в приложении Rails

Вот родительская модель:

<code>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
</code>

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

<code>class TypeWellPhase < ActiveRecord::Base

  belongs_to :type_well
  belongs_to :phase

end
</code>

Вот модель Phase:

<code>class Phase < ActiveRecord::Base
  ... 
  has_many :type_well_phases
  ...
end
</code>

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

<code>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
</code>

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

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

<code>= 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
</code>

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

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

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

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

Бхарат

Ответы на вопрос(2)

f.fields_for :orders, f.object.orders.all(:order => :name) do |order_fields|
Решение Вопроса

у вас есть модели Product и Order:

= 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. Это ваш @ продукт, так что вы можете получить его заказы через.orders, а затем применить необходимую сортировку через.order(:name) (простите за эту небольшую путаницу: заказ / заказы).

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

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

 m_x12 янв. 2016 г., 16:42
@ DevR просто не используйте.order(:name), скорее.sort_by{|o| o.name.to_s }, так что сортировка выполняется в массиве ruby, а не с помощью SQL-запроса.
 Bharat09 мая 2012 г., 04:19
Спасибо за отличное объяснение. У меня просто следующий вопрос: как ты это узнал? Я прочитал и перечитал документацию и даже не мог думать об этом. Другими словами, научи меня ловить рыбу
 m_x30 апр. 2015 г., 14:19
Предупреждение: это решение не сохраняет предварительно созданные объекты, т.е. если вы делаете@product.orders.build в вашем контроллере вы не получите свежий объект, только сохраненные.
 jdoe09 мая 2012 г., 14:46
Нет магии, @ Бхарат. Это в официальной документации на видном месте. Перейти к Api.rubyonrails.org / классы / ActionView / Помощники / ... и прокрутите вниз до слов «Или коллекция для использования».
 Sahil Grover04 дек. 2012 г., 11:00
Помогите мне решить мой вопрос ей / Stackoverflow.com вопросы / 13699285 / ...

Ваш ответ на вопрос