The Whiz of Oz
The Whiz of Oz

Reputation: 7043

Rails4 model ignores parent_id on 'create' action

I have Subcategories which belong to Categories. My app saves (build) all my Subcategories under Subcategory with id = 1, even though my code seems to be ok and it is not supposed to do that:

Subcategories controller:

    def create
      @category = Category.find_by(params[:id])
      @subcategory = @category.subcategories.build(subcategory_params)
      if @subcategory.save
        flash[:success] = "added subcategory"
        redirect_to admin_categories_url
      else
        render :new
      end
    end

...

    private

      def subcategory_params
        params.require(:subcategory).permit(:name, :category_id)
      end  

Subcategory.rb

class Subcategory < ActiveRecord::Base
  belongs_to :category
  has_many :products

  validates :name, presence: true
  validates :category_id, presence: true
end

Form:

<h3>Add a subcategory</h3>

<%= form_for [@category, @subcategory] do |f| %>
  <%= f.text_field :name, placeholder: "Name" %>
  <%= f.submit "Add a subcategory" %>
<% end %>

router:

resources :categories do
    resources :subcategories
  end

URL:

Adding a new subcategory to category with id = 3

http://localhost:3000/categories/3/subcategories/new

Logs:

Started POST "/categories/1/subcategories" for 127.0.0.1 at 2014-04-16 16:04:47 +0400
Processing by SubcategoriesController#create as HTML
  Parameters: {"utf8"=>"✓", authenticity_token"=>"74U3VyAN6NqEjhkuHGNHnPda/yzpc+dIcn2xBJ6Zi2A=", "subcategory"=>{"name"=>"A name"}, "commit"=>"Add subcategory", "category_id"=>"1"}
  User Load (0.2ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = $1 LIMIT 1  [["id", 1]]
  Category Load (0.2ms)  SELECT  "categories".* FROM "categories"  WHERE "categories"."id" = $1 LIMIT 1  [["id", 1]]
   (0.1ms)  BEGIN
  SQL (0.2ms)  INSERT INTO "subcategories" ("category_id", "created_at", "name", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["category_id", 1], ["created_at", "2014-04-16 12:04:47.151729"], ["name", "A name"], ["updated_at", "2014-04-16 12:04:47.151729"]]
   (0.8ms)  COMMIT

Id is 1

What can be the problem here?

Update

When doing

@category = Category.find_by(params[:category_id])

this error comes up:

ERROR:  argument of WHERE must be type boolean, not type integer
LINE 1: SELECT  "categories".* FROM "categories"  WHERE (1) LIMIT 1

If doing

@category = Category.find(params[:category_id])

problem presists

Upvotes: 0

Views: 88

Answers (2)

Rajarshi Das
Rajarshi Das

Reputation: 12320

Look at your parameters it consist category_id not id

 Parameters: {"utf8"=>"✓", authenticity_token"=>"74U3VyAN6NqEjhkuHGNHnPda/yzpc+dIcn2xBJ6Zi2A=", "subcategory"=>{"name"=>"A name"}, "commit"=>"Add subcategory", "category_id"=>"1"}

#=> "category_id"=>"1"

   Category.find_by(category_id: params[:category_id]) 

So you need to do

 def create
  @category = Category.find_by(category_id: params[:category_id])
  @subcategory = @category.subcategories.build(subcategory_params)
  if @subcategory.save
    flash[:success] = "added subcategory"
    redirect_to admin_categories_url
  else
    render :new
  end
end

Upvotes: 1

user740584
user740584

Reputation:

In your create action you are picking up the id of the subcategory, not the category. Change it to:

def create
  @category = Category.find(params[:category_id])
  ...

The same change to setting @category needs to be made in the new method too so that category_id comes back as 3 in the params from the view. Of course this duplication can be also DRYed up using a helper method in the controller.

To see the difference in the id, you can use rake routes and you should see something like:

new_category_subcategory   GET   /categories/:category_id/subcategories/new   subcategories#new

This shows you that it expects the parameter category_id for the id of the category.

Upvotes: 5

Related Questions