Rails - 如何发送一个嵌套在另一个表单中的表单?

9

我在视图中有这个结构:

<%= simple_form_for @user ... %>
  ...
  ...
  <%= render '/hobbies/form', :user => @user %>
  ...
  ...
<% end %>

渲染部分从一个局部加载数据 - 这里有一个表单。表单字段被成功加载(如输入,提交输入,单选按钮等),但是当我查看生成的HTML时,在渲染的表单中缺少<%= form_for...和闭合标签。

这意味着当我从渲染的表单点击提交按钮时,该表单不会被发送,而是发送了“大”表单 - simple_form_for

如何使渲染的表单可发送?

谢谢


3
你不能有两个嵌套的表单,你需要将内部的表单移到外面。 - BroiSatse
正如下面@thedeeno的回答所指出的,您可以使用JavaScript来实现类似嵌套表单的功能。 - Joel Brewer
3个回答

14

简单来说,你不能有两个独立的嵌套表单

你可以使用accepts_nested_attributes_for来嵌套相关表单 - 这取决于后端模型的结构,我会在下面详细说明。

--

表单

你需要知道的最重要的一点是,Rails只创建HTML表单 - 这意味着它们必须遵守所有这些表单规定的约束和规则:

enter image description here

每个表单都有自己的action属性 - 这是浏览器知道发送数据的位置。如果你有多个/嵌套表单,实际上就会有两个这样的"action"属性;这将防止HTML正确地发送表单。

--

嵌套

如果你想使用一些Rails的约定,最好使用accepts_nested_attributes_for方法。这个方法位于模型中,为了有效地使用它,你需要确保你的ActiveRecord associations已正确设置:

#app/models/user.rb
Class User < ActiveRecord::Base
   has_many :hobbies
   accepts_nested_attributes_for :hobbies
end

#app/models/hobby.rb
Class Hobbies < ActiveRecord::Base
   belongs_to :user
end

关联的重要性至关重要 - Rails将会相互传递"嵌套"模型数据。只有在使用ActiveRecord正确关联模型时才会存在嵌套模型数据(如上所示)。

然后你可以按以下方式通过你的控制器/模型传递数据:

#app/controllers/users_controller.rb
Class UsersController < ApplicationController
   def new
       @user = User.new
       @user.hobbies.build # -> essential for nested attributes 
   end

   def create
      @user = User.new(user_params)
      @user.save #-> notice how this saves the @user model only?
   end

   private

   def user_params
      params.require(:user).permit(:user, :attributes, hobbies_attributes: [:hobbies, :attributes])
   end
end

这将允许您将表单中的hobbies部分包含如下:

<%= form_for @user do |f| %>
   <%= f.fields_for :hobbies do |h| %>
       <%= h.text_field :your_attributes %>
   <% end %>
<% end %>

7
嵌套的表单不是有效的html格式。要实现此功能,您必须取消嵌套表单或使用javascript。如果选择javascript方法,您只需捕获表单提交事件,防止默认操作,并手动提交所需表单即可。
编辑:
如果选择javascript方法,请考虑您可能根本不需要两个表单。相反,您可以仅为“子操作”上的按钮添加单击处理程序,该处理程序会发出ajax请求。
或者,如果无法使用javascript并且无法重新排列html,则可以通过从两个表单中提交数据并根据点击哪个提交输入来分别处理每个表单来在服务器上处理此问题。

非常有用,谢谢您先生 - 您知道或有任何示例可以:“捕获表单提交事件,防止默认操作,并手动提交所需的表单。”?那将非常有帮助。 - BenKoshy

2

一个表单内不能再嵌套另一个表单。 如果你正确设置了关联,可以这样做:

class User < ActiveRecord::Base
  has_many :hobbies

  accepts_nested_attributes_for :hobbies
end

class Hobby < ActiveRecord::Base
  belongs_to :user
end

那么在表单中,您可以使用fields_for,如下:

<%= form_for @user do |u| %>
  // user fields
  <%= u.fields_for :hobbies do |h| %>
    // hobbies fields
  <% end %>
  <%= f.submit %>
<% end %>

这将为您提供参数,如:
users_attributes: { name: "xyz", hobbies_attributes: { attribute: "value"} }  

For details checkout accept_nested_attributes_for


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接