【问题标题】:Rails with nested form具有嵌套形式的 Rails
【发布时间】:2014-03-31 23:14:53
【问题描述】:

当我提交表单时,它会创建新的 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

【问题讨论】:

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


    【解决方案1】:

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

    使用上述任何一种方式,您都可以使用 fields_for :users,这会将 users_attributes 发送到控制器。

    您还需要在 Outfitter 模型中接受_nested_attributes_for :users。(http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html)

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

    导轨 4: 你需要在你的强参数上允许 users_attributes(http://edgeapi.rubyonrails.org/classes/ActionController/StrongParameters.html)

    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 和方法,for 将基于此发送数据。

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

      • 表单网址将指向“/outfitters”
      • 方法将是 POST
      • 这会将请求发送到OutfittersController create action
    • 如果@outfitter不是新记录(已保存到数据库,正在更新中)

      • form url 将指向 '/outfitter/:id(@outfitter 记录的 id 作为第一个简单的表单参数传递)'
      • 方法将是 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 存储库并阅读文档。

    享受

    【讨论】:

    • 你可以在这里找到更多关于 form_for 的信息 - apidock.com/rails/ActionView/Helpers/FormHelper/form_for 和 simple_form 这里 github.com/plataformatec/simple_form
    • 所以我添加了 simple_form。但我收到错误“NilClass:Class”的未定义方法“model_name”。我的表单位于页面 pages#index 的模态窗口中。我是否需要为该表单添加一个创建方法到该控制器,或者我可以将它指向outfitters_controller?
    • 能否请您编辑您的问题并提供您是如何实施 simple_form 的?
    • 我已更新表单以包含 simple_form 见上文
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-18
    • 1970-01-01
    • 1970-01-01
    • 2011-06-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多