如何在嵌套模型的属性中设置位置字段,以便我的has_many关系记住它的排序顺序?
我想从索引中设置位置,以便它反映关系被拖入的顺序。
我有一个带有嵌套字段的表单,使用带有JQuery Sortable的cocoon gem,允许每个字段集可以拖动排序。
我想更新保存表单的所有字段的顺序。
答案 0 :(得分:2)
尝试使用“act_as_list”gem。
class TodoList < ActiveRecord::Base
has_many :todo_items, -> { order(position: :asc) }
end
class TodoItem < ActiveRecord::Base
belongs_to :todo_list
acts_as_list scope: :todo_list
end
todo_list = TodoList.find(...)
todo_list.todo_items.first.move_to_bottom
todo_list.todo_items.last.move_higher
答案 1 :(得分:0)
如果你设置了标准的CRUD / restful路由和控制器操作,那么你想要做的就是在嵌套类的实例上调用“update_attributes(:position =&gt; 3)”(在此教育)情况)。
更新嵌套在“简历”下的教育的通常途径是
UPDATE /resumes/123/educations/456
所以,你将对这个网址进行ajax调用。 “UPDATE”方法实际上不是一种更新方法,它通过传递参数"_method" = "UPDATE"
来欺骗,所以你的ajax调用也需要包含这个参数。
所以,基本上,在“完成拖动”事件中,你将要对这个网址进行ajax调用
"/resumes/<%= @resume.id %>/educations/<%= education.id %>"
并传递数据,如
{"_method": "UPDATE", "education[position]": <new position>}
这应该更新教育对象的位置。
另一个问题是,使用acts_as_list,当我们更改一个项目的位置时,我们也希望其他人自动调整其位置。我不确定acts_as_list是否会自动执行此操作。试试吧。
答案 2 :(得分:0)
好的,非ajaxy版本。
假设您的表单是form_for @resume
,这意味着它将调用简历#create或恢复#update action。
如果列表中的所有education
行都有像这样的隐藏字段
<%= hidden_field_tag "resume[education_ids][]", education.id %>
然后在提交表单时,他们将按照表单提交时在页面中显示的顺序[:resume] [:education_ids] 进入数组,这就是你想要的。
该关联为您提供了setter方法Resume#education_ids,允许您按顺序设置关联。
即,您的更新操作(如果它是正常的更新操作)会说类似
@resume = Resume.find_by_id(params[:id])
if @resume.update_attributes(params[:resume])
...
在这种情况下,这将是
@resume.update_attributes(:education_ids => [5,6,2,1])
就像说&#34;按照这个顺序将我的教育设置为有ids 5,6,2,1的那些。
CAVEAT:在我的rails版本中(这可能在后续版本中修复),如果您使用此_ids方法,并且它已经有关联,但是以不同的顺序,它将不会重新排序它们。试一试,看看会发生什么。
答案 3 :(得分:0)
这可能是最好的方法,但我已经在我的控制器中工作了。
p = 1
experiences = []
params[:user][:resume_attributes][:experiences_attributes].each do |e|
e = e.last.merge(:position=>p)
experiences << e
p = p + 1
end
params[:user][:resume_attributes][:experiences_attributes] = experiences
至少说明了我想要实现的目标。