NoMethodError in PostsController#create
Asked Answered
B

4

6

Forgive my ignorance but I am brand new not only to Ruby but programming in general. I am working through the example on edge guides at rubyonrails.org. and am receiving the following error and despite reviewing every piece of code I've typed since the app last worked I am unable to fix it.

NoMethodError in PostsController#create

undefined method `permit' for {"title"=>"", "text"=>""}:ActiveSupport::HashWithIndifferentAccess

And this is what my posts_controller.rb looks like:

class PostsController < ApplicationController
  def new
    @post = Post.new
  end

  def create
    @post = Post.new(params[:post].permit(:title, :text))

    if @post.save
      redirect_to action: :show, id: @post.id
    else
      render 'new'
    end    
  end

  def show
    @post = Post.find{params[:id]}
  end  

  def index
    @posts = Post.all
  end        
end

What am I doing wrong?

Thank you in advance for any help!

Billiebilling answered 19/4, 2013 at 16:16 Comment(2)
The params you get in a controller action is an instance of the ActiveSupport::HashWithIndifferentAccess class, and permit is not an instance method for that class, so this definitely won't work. What are you actually trying to achieve?Iselaisenberg
Have any of the answers solved your problem? If so, please mark it as the correct answer.Churl
C
8

Instead of this line:

@post = Post.new(params[:post].permit(:title, :text))

Try this

 @post = Post.new(params[:post])

It looks like you ran across strong_parameters and had a few tutorial mixups.

If you do want to use strong_parameters, add the gem to your Gemfile and create an initializer with the following:

ActiveRecord::Base.send(:include, ActiveModel::ForbiddenAttributesProtection)

Then your controller can be:

class PostsController < ApplicationController
  def new
    @post = Post.new
  end

  def create
    @post = Post.new(post_params)

    if @post.save
      redirect_to action: :show, id: @post.id
    else
      render 'new'
    end    
  end

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

  def index
    @posts = Post.all
  end    

  private

  def post_params
    params.require(:post).permit(:title, :text)
  end    
end
Churl answered 19/4, 2013 at 16:26 Comment(0)
K
3

Which version of Rails are you using? #permit is a new feature to be added in Rails 4.0 to prevent mass assignment. So if you're on 3.2, you will need to add the strong_parameters gem to support this functionality. Alternatively, you can drop the .permit(:title, :text) in the PostsController#create and add the following to your Post model:

attr_accessible :title, :text

This is done in order to prevent a attacker from tampering with the submitted form data and updating some unauthorized field (e.g. 'is_admin', or something of the sort.

More details here.

Knighthood answered 19/4, 2013 at 16:27 Comment(2)
I'm on 3.2.13. I'll give these a shot and let you all know how it goes. Thank you for the quick responses!!!Billiebilling
This is the answer. The OP is trying to implement a Rails 4 feature in Rails 3.2. attr_accessible is the right answer and the pre-4.0 way to handle mass assignment.Preeminence
P
1

The guide you are following is for rails4 and you must have another version of rails installed.

Follow this for rails 3.2

http://guides.rubyonrails.org/v3.2.13/

Popliteal answered 19/4, 2013 at 16:28 Comment(0)
F
1

In file posts_controller.rb , you need to add those two methods :

class PostsController < ApplicationController
  def new
  end
  def create
    @post = Post.new(params[:post])
    @post.save
    redirect_to @post
  end
end

then you add to the file app/models/post.rb this line :

attr_accessible :title, :text

I hope this helps you to solve the problem :), for me it works ;)

Feoff answered 11/9, 2013 at 22:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.