WordPress Mike
WordPress Mike

Reputation: 458

The action 'create' could not be found for PostsController

I'm working through a Rails tutorial and currently at the CRUD section. There seems to have been some changes from Rails 3 to 4 in regards to the Create action. The tutorial is using Rails 3.x.x and I'm using Rails 4.1.2. I have attempted to adapt my posts controller but I'm getting this error.

posts_controller.rb

class PostsController < ApplicationController
def index
    @posts = Post.all
end

def show
    @post = Post.find(params[:id])
end

def new
    @post = Post.new
    @category = Category.all
end

def create
    @post = Post.new(params[:post])
    if @post.save
        redirect_to posts_path, :notice => "Your post has been saved"
    else
        render "new"
    end
    Category.create(category_params)
end

def edit

end

def update

end

def destroy

end

private

def category_params
    params.require(:name).permit(:id)
end

def create
    Post.create(post_params)
end

private

def post_params

    params.require(:title, :body, :category_id, :author_id)

end

end

models/posts.rb

class Post < ActiveRecord::Base
belongs_to :category
end

I can tell that the post contoller is wrong but nothing I have tried has worked.

UPDATE

Server log for create action

Started POST "/posts" for 127.0.0.1 at 2014-06-24 19:52:22 -0400
Processing by PostsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"w/ViBIFCFaaT1yIZaBkjWhjUjZ0LKXrT+9sOIN0c2q4=", "post"=>{"title"=>"teste", "body"=>"testest", "category_id"=>"4"}, "commit"=>"Add Post"}
Unpermitted parameters: utf8, authenticity_token, post, commit
  [1m[36m (0.0ms)[0m  [1mbegin transaction[0m
  [1m[35mSQL (0.2ms)[0m  INSERT INTO "posts" ("created_at", "updated_at") VALUES (?, ?)  [["created_at", "2014-06-24 23:52:22.825483"], ["updated_at", "2014-06-24 23:52:22.825483"]]
  [1m[36m (1.3ms)[0m  [1mcommit transaction[0m
Redirected to http://domain:3000/posts
Unpermitted parameters: utf8, authenticity_token, post, commit
  [1m[35m (0.0ms)[0m  begin transaction
  [1m[36mSQL (0.2ms)[0m  [1mINSERT INTO "categories" ("created_at", "updated_at") VALUES (?, ?)[0m  [["created_at", "2014-06-24 23:52:22.828618"], ["updated_at", "2014-06-24 23:52:22.828618"]]
  [1m[35m (1.1ms)[0m  commit transaction
Completed 302 Found in 6ms (ActiveRecord: 2.8ms)

Upvotes: 1

Views: 584

Answers (3)

Richard Peck
Richard Peck

Reputation: 76774

Strong Params

You need to use strong params in Rails 4:

#app/controllers/posts_controller.rb
Class PostsController < ApplicationController
   def create
      @post = Post.new(post_params)
      @post.save
   end

   private

   def post_params
       parmas.require(:post).permit(:param1, :param2, :param3, :param4)
   end
end 

--

Routes

Secondly, you need to consider resourceful routes

When you use routing in Rails, the default is to create routes around particular "resources" (I.E around controllers / models). Basically, the routes you have will work like this:

#config/routes.rb
resources :posts

You may know this already, but as you're following the tutorial, you'll be able to see how the routing mechanism works, allowing you to route your paths accordingly

enter image description here

Something you need to also consider is, as @san pointed out, you need to make sure you only have one resourceful route per controller (you currently have two create actions)

Upvotes: 0

Jorge de los Santos
Jorge de los Santos

Reputation: 4633

You have two create methods, and one is private. So you ruby can't access to it.

Edit: I've added the params permit. You doesn't seem to be sending this id.

Your controller should look like:

class PostsController < ApplicationController
  def index
    @posts = Post.all
  end

  def show
    @post = Post.find(params[:id])
  end

  def new
    @post = Post.new
    @category = Category.all
  end

  def create
    @post = Post.new(post_params)
    if @post.save
        redirect_to posts_path, :notice => "Your post has been saved"
    else
        render "new"
    end
    Category.create(category_params)
  end

  def edit
  end

  def update
  end

  def destroy
  end

  private

  def category_params
    params.require(:post).permit(:category_id)
  end

  def post_params
    params.require(:post).permit(:title, :body, :category_id, :author_id)
  end

end

Upvotes: 1

San
San

Reputation: 1954

Your controller is a mess. It has two "create" actions and two "private" declarations. Use scaffold generator to generate a Controller for you. Read up more on that here: http://guides.rubyonrails.org/command_line.html

Upvotes: 1

Related Questions