1

如何在嵌套模型的属性中设置位置字段,以便我的 has_many 关系记住它的排序顺序?

我想从索引中设置位置,以便它反映关系被拖入的顺序。

我有一个带有嵌套字段的表单,使用带有 JQuery Sortable 的 cocoon gem,允许每个字段集都可以拖动排序。

我想在保存表单时更新所有字段的顺序。

4

4 回答 4

1

尝试使用“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

参考:https ://github.com/swanandp/acts_as_list

于 2017-11-23T04:40:50.367 回答
0

如果您设置了标准 CRUD/restful 路由和控制器操作,那么您要做的就是在嵌套类的实例上调用“update_attributes(:position => 3)”(在这种情况下为教育)。

更新嵌套在“简历”下的教育的通常途径是

UPDATE  /resumes/123/educations/456

因此,您将对这个 url 进行 ajax 调用。“UPDATE”方法并不是真正的更新方法,它是通过传递参数来进行欺骗的"_method" = "UPDATE",因此您的 ajax 调用也需要包含此参数。

因此,基本上,在“完成拖动”事件中,您将对这个 url 进行 ajax 调用

"/resumes/<%= @resume.id %>/educations/<%= education.id %>"

并传递数据

{"_method": "UPDATE", "education[position]": <new position>}

这应该更新教育对象的位置。

剩下的另一个问题是,对于acts_as_list,当我们改变一个项目的位置时,我们希望其他项目也自动调整它们的位置。我不确定acts_as_list 是否会自动执行此操作。试试看。

于 2015-06-12T15:30:48.150 回答
0

好的,非ajaxy版本。

假设您的表单是 a form_for @resume,这意味着它将调用 resumes#create 或 resumes#update 操作。

如果education列表中的所有行都有这样的隐藏字段

<%= hidden_field_tag "resume[education_ids][]", education.id %>

那么当表单提交时,它们将按照提交表单时在页面中出现的顺序进入 params[:resume][:education_ids] 中的数组,这就是你想要的。

关联为您提供了设置方法 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])

这就像说“按顺序将我的教育设置为 ID 为 5、6、2、1 的教育。

警告:在我的 rails 版本中(这可能在后续版本中修复),如果您使用此 _ids 方法,并且它已经具有关联,但以不同的顺序,它不会重新排序它们。试一试,看看会发生什么。

于 2015-06-12T15:51:54.867 回答
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    

这至少说明了我想要实现的目标。

于 2015-06-12T17:11:43.407 回答