【问题标题】:Set Position Value from Index for nested model attributes为嵌套模型属性设置索引中的位置值
【发布时间】:2015-06-12 15:04:23
【问题描述】:

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

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

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

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

【问题讨论】:

  • 你们关系中的两个模型类的名称是什么?
  • @MaxWilliams - 简历和教育。恢复有_许多教育

标签: ruby-on-rails ruby-on-rails-4 cocoon-gem acts-as-list


【解决方案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

【讨论】:

    【解决方案2】:

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

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

    UPDATE  /resumes/123/educations/456
    

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

    所以,基本上,在“完成拖动”事件中,您将对该网址进行 ajax 调用

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

    并像传递数据

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

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

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

    【讨论】:

    • 啊,当你说你使用 jquery sortable 时,我假设你在用户完成拖动项目时进行 ajax 调用。
    【解决方案3】:

    好的,非 ajaxy 版本。

    假设您的表单是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 的教育,按此顺序。

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

    【讨论】:

    • 感谢@MaxWilliams - 该表单可以添加和删除教育项目以及重新排序它们。这就是为什么我需要从参数中的位置获取每个教育记录的位置。这是索引。
    • 所以这行不通。我不知道所有记录的ID。事实上,有些人在保存时没有 id,因为它们是新的。
    • 你需要在你的问题中解释这些东西,即你的要求。我猜是因为你没有详细说明你想做什么。
    • 感谢 max,感谢您尝试帮助我。我添加了一个有效但丑陋的答案,可能会进一步澄清。
    【解决方案4】:

    这不是最好的方法,但我已经在我的控制器中进行了这项工作。

    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    
    

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

    【讨论】:

    • 您能否将params[:user] 的一些示例值复制到此答案中,以便我们看看这里发生了什么?
    猜你喜欢
    • 1970-01-01
    • 2010-11-05
    • 1970-01-01
    • 2015-05-19
    • 1970-01-01
    • 1970-01-01
    • 2015-12-19
    • 1970-01-01
    • 2013-12-23
    相关资源
    最近更新 更多