รูปแบบที่ซ้อนกันของ Rails 4 ไม่ได้สร้างวัตถุที่ยอมรับได้_nested_attributes_for

ฉันกำลังพยายามทำให้หมวดหมู่และหมวดหมู่ย่อยทำงานได้ จนถึงตอนนี้ ฉันสามารถสร้างหมวดหมู่และเพิ่มหมวดหมู่ย่อยลงไปได้ เมื่อฉันส่งแบบฟอร์ม subcategories_attributes จะส่ง แต่ไม่มีการสร้างบันทึกหมวดหมู่ย่อย โปรดช่วยด้วย ฉันกำลังดึงผมออกมาตรงนี้ และดูเหมือนว่าบทเรียนช่วยสอนใดจะช่วยไม่ได้

category.rb

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

หมวดหมู่ย่อย.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 %>

Params Hash (เมื่อส่ง):

  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"} 

ขอบคุณล่วงหน้า!


person DaveahamLincoln    schedule 28.04.2014    source แหล่งที่มา


คำตอบ (1)


subcategories_attributes ถูกส่งอย่างถูกต้องภายในแฮช params ของคุณ แต่แอตทริบิวต์ content ขาดหายไป

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

โปรดสังเกตว่าไม่มีการส่งผ่านคีย์ content ดังนั้น บันทึกหมวดหมู่ย่อยทั้งหมดที่ส่งใน subcategories_attributes จะถูก ถูกปฏิเสธ เนื่องจากเงื่อนไขที่คุณระบุไว้ในโมเดล Category:

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

โปรดสังเกตส่วน :reject_if => lambda {|a| a[:content].blank?} ด้านบน ซึ่งจะปฏิเสธระเบียนทั้งหมดที่ content หายไป

อัปเดต

เมื่อฉันไปที่การดำเนินการแก้ไข ฟิลด์ต่างๆ จะไม่ปรากฏขึ้น แม้ว่าจะถูกเพิ่มลงในฐานข้อมูลตามที่ตั้งใจไว้ (และแสดงในรูปแบบอื่น)

ตั้งค่าตัวแปรในการดำเนินการ edit และ new ดังนี้:

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

def edit
  @subcategories = @category.subcategories  ## Added
end

อัปเดต fields_for ในแบบฟอร์ม edit ดังนี้:

<%= f.fields_for :subcategories, @subcategories do |builder|%>
person Kirti Thorat    schedule 28.04.2014
comment
ฉันควรใช้ lambda {|a| a[:name].blank?} แทนเหรอ? ฉันค่อนข้างใหม่กับ lambdas ไม่แน่ใจว่า :content เป็นสัญลักษณ์ในตัวสำหรับสิ่งต่าง ๆ ที่นี่หรือไม่ - person DaveahamLincoln; 29.04.2014
comment
ใช่คุณสามารถ. มันเป็นเพียงการตรวจสอบคุณลักษณะอื่น เมื่อคุณส่งฟิลด์ :name สำหรับหมวดหมู่ย่อยใน subcategories_attributes จะช่วยแก้ไขปัญหาของคุณได้ subcategories จะถูกบันทึกสำเร็จ - person Kirti Thorat; 29.04.2014
comment
นั่นแก้ไขมัน! ขอบคุณ! - person DaveahamLincoln; 01.05.2014
comment
อีกคำถามหนึ่ง - เมื่อฉันไปที่การดำเนินการแก้ไข ฟิลด์ต่างๆ จะไม่ปรากฏขึ้น แม้ว่าจะถูกเพิ่มลงในฐานข้อมูลตามที่ตั้งใจไว้ (และแสดงในรูปแบบอื่น) ฉันต้องการที่จะลบหมวดหมู่ย่อยออกจากการดำเนินการแก้ไขได้หากจำเป็น ขออภัยหากเป็นการรบกวน... - person DaveahamLincoln; 01.05.2014
comment
ดูส่วน UPDATE ในคำตอบ - person Kirti Thorat; 01.05.2014
comment
แก้ไข ฉันเข้าใจผิด รหัสยังคงใช้งานไม่ได้ โดยส่งคืนเมธอดที่ไม่ได้กำหนด `model_name' สำหรับข้อผิดพลาด #‹Class:0x000000053b6410› ในการดำเนินการแก้ไข โดยชี้ไปที่บรรทัด ‹%f.fields_for @subcategories, :subcategories do |builder|%› - person DaveahamLincoln; 02.05.2014
comment
ตรวจสอบคำตอบที่อัปเดต fields_for นอกจากนี้ = หายไปใน <%= fields_for .....%> คุณจะต้องใช้มันเพื่อแสดงเอาต์พุตของ fields_for ในมุมมอง - person Kirti Thorat; 02.05.2014
comment
นั่นเท่ากับสัญญาณ แก้ไขทุกอย่าง! รับได้สวย! ขอขอบคุณสำหรับความช่วยเหลือจริงๆ! - person DaveahamLincoln; 03.05.2014
comment
ไม่มีปัญหา. ดีใจที่ได้ช่วย :) - person Kirti Thorat; 03.05.2014