在Rails应用程序中使用accepts_nested_attributes_for时,如何维护嵌套属性的顺序
这是父模型:
class TypeWell :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)中添加嵌套记录,如下所示:
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
一切都按预期工作; 大部分的时间。 但是,有时表单中Child行的顺序在保存后会搞乱。 顺序在此应用程序中很重要,这就是我在控制器中的私有方法中明确执行此排序的原因。
我使用“cocoon”gem来添加删除子记录。 我不确定为什么这个订单有时搞砸了。
很抱歉这么长的post,但我想提前提供所有相关细节。
感谢任何指针。
巴拉特
我会以更通用的方式解释你。 比如说,您有产品和订单型号:
= 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|
如您所见,作为form_for
块参数的f
变量具有方法object
。 这是你的@product,所以你可以通过.orders
获取它的订单,然后通过.orders
.order(:name)
应用所需的排序(抱歉这个小混乱:订单/订单)。
解决方案的关键是您可以将已排序的订单作为fields_for
的第二个参数fields_for
。
PS您使用simple_form gem不会影响我的解决方案。 如果你向帮助者添加’simple_’,它会起作用。 只是希望我的回答对其他人更有帮助,而不是与任务有关。
如果您使用的是Rails 2.3.14或更早版本,则必须使用:
f.fields_for :orders, f.object.orders.all(:order => :name) do |order_fields|