具有嵌套形式的Rails

时间:2014-03-31 23:14:53

标签: ruby-on-rails erb nested-forms

当我提交表单时,它会创建新的Outfitter,但它不会创建新用户。在日志中它表示“未经许可的参数:utf8,authenticity_token,first_name,last_name,email,password,password_confirmation,commit'

模态html :(模态在application.html.erb。页面是localhost:3000 / pages / index)

<div id="popup-outfitter-signup" class="modal popup">
 <div class="modal-main rounded-10px">
 <div class="modal-title">
  Create your Outfitter<br/>
 </div><!-- end .modal-title --> 
 <%= simple_form_for :outfitter do |f| %>
 <div class="modal-message">
  <p>
  <%= label_tag :name, "Outfitter Name" %><br/>
    <%= text_field_tag :name, params[:name], class: 'input-txt rounded-2px' %>
  </p>
  <p>
    <%= label_tag :address, "Address:" %><br/>
    <%= text_field_tag :address, params[:address], class: 'input-txt rounded-2px' %>
  </p>
  <p>
    <%= label_tag :business_phone, "Phone:" %><br/>
    <%= text_field_tag :business_phone, params[:business_phone], class: 'input-txt rounded-2px' %>
  </p>

    <%= simple_fields_for :users do %>
      <p>
        <%= label_tag :first_name, "First Name" %><br/>
        <%= text_field_tag :first_name, params[:first_name], class: 'input-txt rounded-2px' %>
      </p>
      <p>
        <%= label_tag :last_name, "Last Name:" %><br/>
        <%= text_field_tag :last_name, params[:last_name], class: 'input-txt rounded-2px' %>
      </p>
      <p>
        <%= label_tag :email, "Email:" %><br/>
        <%= text_field_tag :email, params[:email], class: 'input-txt rounded-2px' %>
      </p>
      <p>
        <%= label_tag :password, "Password:" %><br/>
        <%= password_field_tag :password, params[:password], class: 'input-txt rounded-2px' %>
      </p>
      <p>
        <%= label_tag :password_confirmation, "Password Confirmation:" %><br/>
        <%= password_field_tag :password_confirmation, params[:password_confirmation], class: 'input-txt rounded-2px' %>
      </p>
    <% end %>

  <div class="button rounded-2px trans-all">
    <%= submit_tag "Signup", class: 'send-btn rounded-2px trans-all' %>
  </div>
  <br/>
 </div>
 <% end %>
 </div><!-- end .modal-main -->
</div><!-- end .modal -->

outfitters_controller.rb

def new
  @outfitter = Outfitter.new
  @outfitter.users.build
end

1 个答案:

答案 0 :(得分:3)

首先,如果要构建映射到模型的表单,我建议使用rails form_forsimple_form gem。

使用上述任何一种方法都可以使用fields_for:users,它们会将users_attributes发送给控制器。

您还需要在Outfitter模型中使用accepts_nested_attributes_for:用户。(http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

如果您使用的是Rails 3或Rails 4,则会有一个额外的步骤:

Rails 4:  您需要在强参数(http://edgeapi.rubyonrails.org/classes/ActionController/StrongParameters.html

上允许users_attributes
params.require(:outfitter).permit(users_attributes: [])

Rails 3:您必须将:users_attributes添加到您的模型的attr_accessible

class Outfitter < ActiveRecord::Base
    attr_accessible :users_attributes
    accepts_nested_attributes_for :users_attributes
    ...
end

希望这可以帮到你。

根据更新的问题编辑1

当使用简单表单时,您需要传递某个类的实例,以便它可以为该特定类构建for并将表单变量传递给该块:

# @outfitter will be the one you instantiated your new action
<%= simple_form_for @outfitter do |f| %>
  #form inputs go here, see next code block for more info
<% end %>

简单表单将采用您的@outfitter实例,检查其记录是否已保存到数据库中,并将定义用于根据该数据提交数据的URL和方法。

  • 如果@outfitter是新记录(这是您的情况)

    • 表单网址将指向&#39; / outfitters&#39;
    • 方法将是POST
    • 这会将请求发送到OutfittersController创建操作
  • 如果@outfitter不是新记录(已保存到数据库中,现在正在更新)

    • 表单网址将指向&#39; / outfitter /:id(作为第一个简单表单参数传递的@outfitter记录的ID)&#39;
    • 方法将是PATCH
    • 这会将请求发送到OutfittersController更新操作

要在simple_form块内创建输入,请执行以下操作:

<%= simple_form_for @outfitter do |f| %>
  # f - is the form object
  # input - is the method called on the form to create the input
  # :name - is the attribute name that will be mapped to this input
  # you can only create inputs for the attributes in your class
  <%= f.input :name %>
  <%= f.input :address %>
<% end %>
  • 默认表单默认情况下会为输入创建带有属性名称的标签

要使用简单表单创建嵌套表单,您必须执行以下操作

<%= simple_form_for @outfitter do |f| %>
  # calling f.simple_fields_for will ensure simple_form knows the users form is nested under outfitter form
  <%= f.simple_fields_for :users do |user_form| %>
    # user_form is the form object nested under outfitters form
    # every input method inside this block should be called on user_form
    <%= user_form.input :name %>
    <%= user_form.input :address %>
  <% end %>
<% end %>

您的完整内容如下:

<%= simple_form_for @outfitter do |f| %>
  <div class="modal-message">
  <p>
    # input_html is used to parse attributes to be added to the input
    <%= f.input :name, input_html: { class: 'input-txt rounded-2px' } %>
  </p>
  <p>
    <%= f.input :address, input_html: { class: 'input-txt rounded-2px' } %>
  </p>
  <p>
    <%= f.input :business_phone, input_html: { class: 'input-txt rounded-2px' } %>
  </p>

  <%= f.simple_fields_for :users do |user_form| %>
    <p>
      <%= f.input :first_name, input_html: { class: 'input-txt rounded-2px' } %>
    </p>        
    <p>
      <%= f.input :last_name, input_html: { class: 'input-txt rounded-2px' } %>
    </p>
    <p>
      <%= f.input :email, input_html: { class: 'input-txt rounded-2px' } %>
    </p>
    <p>
      <%= f.input :password, input_html: { class: 'input-txt rounded-2px' } %>
    </p>
    <p>
      <%= f.input :password_confirmation, input_html: { class: 'input-txt rounded-2px' } %>
    </p>
  <% end %>

  <div class="button rounded-2px trans-all">
    <%= f.submit 'Signup', class: 'send-btn rounded-2px trans-all' %>
  </div>
<% end %>

你可以用简单的形式做更多的事情,确保你去他们的github回购并阅读文档。

享受