akhanaton
akhanaton

Reputation: 13

ActiveRecord nested value update fails

I am trying to update a product please see code below. I can't seem to update the category. Any help is welcome.

Product model:

class Product < ActiveRecord::Base
  belongs_to :category

  accepts_nested_attributes_for :category

  def category_name
    category.try(:name)
  end

  def category_name=(name)
    Category.find_or_create_by(name: name) if name.present?
  end
end

Category model:

class Category < ActiveRecord::Base
  has_many :products
end

Products controller:

class ProductsController < ApplicationController
  def index
    @products = Product.all
  end

  def show
    @product = Product.find(params[:id])
  end

  def edit
    @product = Product.find(params[:id])
  end

  def update
     @product = Product.find(params[:id])
     @product.update(products_params)
     redirect_to @product
  end

  private

  def products_params
    products_params = params.require(:product).permit(:name, :category_id, category_attributes: [:category_name])
  end
end

Upvotes: 0

Views: 27

Answers (1)

Jorge de los Santos
Jorge de los Santos

Reputation: 4633

You are creating a setter inside the Product class but you are passing the attribute into the nested model. You should chose one of the solutions. Best one is to delegate in rails the nester attribute handling.

http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

class Product < ActiveRecord::Base
  belongs_to :category
  accepts_nested_attributes_for :category
end

class Category < ActiveRecord::Base
  has_many :products
end

class ProductsController < ApplicationController
  def index
    @products = Product.all
  end

  def show
    @product = Product.find(params[:id])
  end

  def edit
    @product = Product.find(params[:id])
  end

  def update
     @product = Product.find(params[:id])
     @product.update(products_params)
     redirect_to @product
  end

  private

  def products_params
    params.require(:product).permit(:name, category_attributes: [:name])
  end
end

Upvotes: 1

Related Questions