【问题标题】:Rails 4 nested form not creating the objects which it accepts_nested_attributes_forRails 4嵌套表单没有创建它接受的对象_nested_attributes_for
【发布时间】:2014-04-28 17:56:28
【问题描述】:

我正在尝试让类别和子类别发挥作用。到目前为止,我可以创建类别并向它们添加子类别。当我提交表单时,subcategories_attributes 发送,但没有创建 Subcategory 记录。请帮忙,我在这里拉头发,但似乎没有任何教程有帮助。

category.rb

class Category < ActiveRecord::Base
   has_many :subcategories, :dependent => :destroy
   accepts_nested_attributes_for :subcategories, :reject_if => lambda {|a| 
   a[:content].blank?}
end

subcategory.rb

class Subcategory < ActiveRecord::Base
   belongs_to :category
end

categories_controller.rb

class CategoriesController < ApplicationController
   before_action :set_category, only: [:show, :edit, :update, :destroy]

def index
   @categories = Category.all
end

def show
end

def new
   @category = Category.new
   @category.subcategories.build
end

def edit
end

def create
   @category = Category.new(category_params)

   respond_to do |format|
     if @category.save
       format.html { redirect_to @category, notice: 'Category was successfully 
       created.' }
       format.json { render action: 'show', status: :created, location: @category }
     else
       format.html { render action: 'new' }
       format.json { render json: @category.errors, status: :unprocessable_entity }
     end
   end
end

def update
   respond_to do |format|
     if @category.update(category_params)
       format.html { redirect_to @category, notice: 'Category was successfully 
       updated.' }
       format.json { head :no_content }
     else
       format.html { render action: 'edit' }
       format.json { render json: @category.errors, status: :unprocessable_entity }
     end
   end
end

def destroy
   @category.destroy
   respond_to do |format|
     format.html { redirect_to categories_url }
     format.json { head :no_content }
   end
end

private
# Use callbacks to share common setup or constraints between actions.
  def set_category
    @category = Category.find(params[:id])
  end

# Never trust parameters from the scary internet, only allow the white list through.
  def category_params
    params.require(:category).permit(:name, subcategories_attributes: [:id, :name, 
    :_destroy])
  end
end

_form.html.erb

<%= nested_form_for(@category) do |f| %>
  <% if @category.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@category.errors.count, "error") %> prohibited this category 
      from being saved:</h2>   
      <ul>
      <% @category.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </div>

  <%f.fields_for :subcategories do |builder|%>
    <p>
      <b>Subcategory</b>
      <%=builder.text_field :name%>
      <%=builder.link_to_remove "Remove"%>
    <p>
  <%end%>
    <p>
      <%=f.link_to_add "Add a Subcategory", :subcategories%>
    </p>    

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

参数哈希(提交时):

  Parameters: {"utf8"=>"✓", 
  "authenticity_token"=>"19FxRnWF1F3BD4QZIkkce4arkOPt/BMkWFw6Z+vpV+8=", "category"=>
  {"name"=>"Test", "subcategories_attributes"=>{"1398706662184"=>{"name"=>"TS1", 
  "_destroy"=>"false"}, "1398706664804"=>{"name"=>"TS2", "_destroy"=>"false"}}}, 
  "commit"=>"Create Category"} 

提前致谢!

【问题讨论】:

    标签: ruby-on-rails-4 parameters nested-forms nested-attributes


    【解决方案1】:

    subcategories_attributes 在您的 params 哈希中正确发送,但其中缺少 content 属性。

    "subcategories_attributes"=>{"1398706662184"=>{"name"=>"TS1", 
      "_destroy"=>"false"}, "1398706664804"=>{"name"=>"TS2", "_destroy"=>"false"}}
    

    请注意,没有通过 content 键。 因此,由于您在 Category 模型中指定的条件,subcategories_attributes 中传递的所有子类别记录都REJECTED

     accepts_nested_attributes_for :subcategories, :reject_if => lambda {|a| 
       a[:content].blank?}
    

    注意上面的:reject_if =&gt; lambda {|a| a[:content].blank?} 部分,这将拒绝所有缺少content 的记录。

    更新

    当我进行编辑操作时,尽管按预期添加到数据库中(并且在其他 表格)。

    editnew 操作中设置变量如下:

    def new
     @category = Category.new
     @subcategories = @category.subcategories.build ## Added
    end
    
    def edit
      @subcategories = @category.subcategories  ## Added
    end
    

    edit 表单中更新fields_for 如下:

    <%= f.fields_for :subcategories, @subcategories do |builder|%>
    

    【讨论】:

    • 所以我应该使用 lambda {|a| a[:name].blank?} 代替?我对 lambdas 很陌生,不确定 :content 是否是“这里的东西”的内置符号。
    • 是的,你可以。它只是对另一个属性的检查。当您在subcategories_attributes 中为子类别传递:name 字段时,它将解决您的问题。 subcategories 将被成功保存。
    • 解决了!谢谢!
    • 另一个问题-当我进行编辑操作时,尽管按预期添加到数据库中(并以其他形式显示),但这些字段没有显示。如果需要,我希望能够从编辑操作中删除子类别。对不起,如果我打扰了......
    • 查看答案中的更新部分。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多