s-cho-m
s-cho-m

Reputation: 1027

How to use accepts_nested_attributes_for with rails?

I have read these documents:

My source:

Model

app/models/product.rb

class Product < ActiveRecord::Base
  has_many :product_items, foreign_key: :product_id, :dependent => :destroy
  accepts_nested_attributes_for :product_items
end

app/models/product_item.rb

class ProductItem < ActiveRecord::Base
  belongs_to :product
end

Controller

app/controllers/products_controller.rb

class ProductController < ApplicationController
  def new
    @product = Product.new
  end

  def create
    @product = Product.new(product_params)
    respond_to do |format|
      if @product.save
        format.html { redirect_to root_path }
      else
        format.html { render :new }
      end
    end
  end

  private

  def product_params
    params.require(:product).permit(:name, product_items_attributes: [ :description ])
  end
end

View

app/views/products/_form.html.erb

<%= form_for(product, url: path) do |f| %>
  <%= f.label :name %>
  <%= f.text_field :name %>

  <%= f.fields_for :product_items do |item_form| %>
    <%= item_form.label :description %>
    <%= item_form.text_field :description %>
  <% end %>

  <%= f.submit 'Submit' %>
<% end %>

I can save the product data to the database, but it can't save product_items.


Edit

Add my post data after submit my form:

utf8:✓
authenticity_token:c5sdmoyLoN01Fxa55q6ahTQripx0GZvWU/d27C]asfdawofX9gw==
product[name]:apple
product[product_items][description]:good
commit:Submit

Edit 2

Add rails log:

Started POST "/products" for 10.0.2.2 at 2015-09-15 13:00:57 +0900
Processing by ProductController#create as HTML
I, [2015-09-15T13:00:58.039924 #28053]  INFO -- :   Parameters: {"utf8"=>"✓", "authenticity_token"=>"bilBzgOLc2/ZRUFhJORn+CJvCHkVJSsHQTg1V/roifoHxi9IRA==", "product"=>{"name"=>"apple", "product_items"=>{"description"=>"good"}}, "commit"=>"Submit"}

Upvotes: 0

Views: 76

Answers (2)

Pavan
Pavan

Reputation: 33552

Your new method should like below in order to save product_items

def new
  @product = Product.new
  @product.product_items.build
end

You should also change your product_params like below for the update to work correctly in future.

def product_params
  params.require(:product).permit(:name, product_items_attributes: [ :id, :description ])
end

Upvotes: 2

Prakash Laxkar
Prakash Laxkar

Reputation: 854

Update your controller action product_params

def product_params
  params.require(:product).permit(:name, product_items_attributes: [:id, :description, :_destroy ])
end

Either you can use nested_form gem which provide you complete demo and function control. Here is link https://github.com/ryanb/nested_form

Upvotes: 0

Related Questions