Ruby on rails Rails-在同一页面上提交多个表单

Ruby on rails Rails-在同一页面上提交多个表单,ruby-on-rails,forms,Ruby On Rails,Forms,型号: 用户有费用。费用有地位 查看: 当用户添加他们的费用时,他们会显示在一个列表中。每个费用行的末尾都有一个表单按钮,用于提交费用(更改费用的状态)。这允许用户添加尚未完全填写的费用,并在准备就绪时提交。此页面上没有父表单,只有表单按钮,用于将费用提交给更改状态的方法,然后重新加载页面 目前它工作得很好,但用户要求能够“提交”视图上显示的所有费用,只需一个按钮 问题: 在rails中处理此问题的正确方法是什么?我是否应该找到一种方法来收集费用id的数组,然后提交一个单独的表单?是否有一种方法

型号: 用户有费用。费用有地位

查看: 当用户添加他们的费用时,他们会显示在一个列表中。每个费用行的末尾都有一个表单按钮,用于提交费用(更改费用的状态)。这允许用户添加尚未完全填写的费用,并在准备就绪时提交。此页面上没有父表单,只有表单按钮,用于将费用提交给更改状态的方法,然后重新加载页面

目前它工作得很好,但用户要求能够“提交”视图上显示的所有费用,只需一个按钮

问题: 在rails中处理此问题的正确方法是什么?我是否应该找到一种方法来收集费用id的数组,然后提交一个单独的表单?是否有一种方法可以要求视图中存在一组具有特定状态的记录


谢谢

您应该做的第一件事是更改表单以远程提交,即发出ajax请求。那么你就不会重新加载整个页面了。查看Rails的各种“远程”表单帮助程序,例如“远程表单”


然后,编写一个javascript函数来提交自页面加载以来已更改的输入的所有表单。您可能希望在每个输入中的onchange事件中向父窗体添加一个“已更改”(或类似)类,以便于实现这一点。我认为这是处理你所问的“地位”问题的最好方法。制作一个调用此函数的“全部提交”按钮。

如果我考虑正确的话,另一个选项是将页面包装成
用户
表单。然后你可以做一些像

<%= form_for(@user) do |f| %>
  <% @user.expenses.each do |expense| %>
    <% f.fields_for expense do |e| %>
      <!-- expense form -->
    <% end %>
  <% end >
<% end %>

这是你可以作为一个整体提交的东西。我很难想象一个单独的费用增加会是什么样子,但希望这能让你走得更远一点


编辑:除了页面上有此
用户
表单外,您还可以有一个“额外的”
费用
表单来创建费用。提交新费用时,该费用将显示在用户表单下的列表中,可以作为组的一部分或单独(作为1的“组”的一部分)对其进行编辑或提交。

自定义控制器操作:

def update_all_expense_statuses
  expenses = current_user.expenses
  ExpenseUpdater.new(expenses).update_expense
  redirect_to :back
end
费用更新程序类:

class ExpenseUpdater
  def initialize(expenses)
     @expenses = expenses
  end

  def update_expense
    @expenses.each do |expense|
      expense.update_attributes(status: 'paid')
      expense.save
    end
  end
end
这只是使用自定义控制器操作更新所有用户费用的一种方法的示例。只需从链接_调用控制器方法即可:

<%= link_to "Update all expenses", update_all_expense_statuses_path %>


记住将其添加到您的路线中。希望这有帮助。

使用表单/服务对象来封装费用报告

谢谢,我会研究一下。我希望避免使用javascript,除非它是唯一的选择。如果你想避免使用javascript,你仍然可以尝试使用params散列和自定义方法来解决问题。我不知道收集所有表单参数有多难。您可以更改表单,以便将所有费用输入封装在一个表单中,用户立即提交所有更改。您需要按照riecaro2的建议编写一个自定义控制器方法。构造数据的一个好方法是提交一个散列,其中键是费用对象的ID,每个都指向更新该对象的属性散列。谢谢,这绝对是我可以做的。我已经在页面上添加了一个新的费用表单——这意味着嵌套表单吗?我想总共有两个表单:一个是“新费用”表单,另一个是每个现有费用都有一个项目的表单。(后一种形式是我上面的代码所演示的。)这两种形式将相互独立运行,并且为了用户的方便,只能共存于同一个页面。非常好,我有一些过滤器要添加,但这肯定是一种方法。非常感谢。