Shaun Frost Duke Jackson
Shaun Frost Duke Jackson

Reputation: 1266

The wonderful ActiveModel::ForbiddenAttributesError

I've been using strong_params and trying to get a object create to pass. I have two questions.

  1. How do you find out which attribute is causing the issue?
  2. What am I missing in the code below?

Lets start with the error, the log tells me nothing.

ActiveModel::ForbiddenAttributesError in JobsController#create

Just for giggles, here is the log which I don't see very useful:

Started POST "/jobs" for 127.0.0.1 at 2013-12-17 22:03:59 +0000
Processing by JobsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"Ohq4lVqPVMpjzbZwCfJNYBL78TAcoC0WZLSmpCzMD3k=", "job"=>{"job_title"=>"Junior Rails Developer", "job_description"=>"A new position getig nsomethfins lansnana", "languages"=>["", "Rails", "Ruby"], "country_code"=>"AO", "job_type"=>"Full-Time", "job_salary"=>"30000", "job_level"=>"Junior"}, "commit"=>"Create Job"}
  User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1
Completed 500 Internal Server Error in 8ms

ActiveModel::ForbiddenAttributesError (ActiveModel::ForbiddenAttributesError):

Makes sense, but then if I look at my create:

def create
    binding.pry
    @job = Job.new(job_params)

    respond_to do |format|
      if @job.save
        format.html { redirect_to @job, notice: 'Job was successfully created.' }
        format.json { render action: 'show', status: :created, location: @job }
      else
        format.html { render action: 'new' }
        format.json { render json: @job.errors, status: :unprocessable_entity }
      end
    end
  end

Strong_params:

 def job_params
      params.require(:job).permit(:job_title, :job_level, :job_description, :job_salary,
                                  :country_code, :job_type, :state, :languages => [])
    end

I am mainly interested in finding how to find out where the problem is for future as it's seems like a needle in haystack error.

Upvotes: 7

Views: 406

Answers (3)

RubyNewby
RubyNewby

Reputation: 11

It probably doesn't apply in this case but I have had the type of problem with Rails 4, but only with the create action. Looking through the full stack trace in teh development log showed some references to CanCan and the ability model which I've used for access control.

I started off using the load_and_authorize_resource as recommended at the top of the controller, but when I removed it and just permissioned each action 'long hand', the problem with the parameters disappeared.

Upvotes: 1

severin
severin

Reputation: 10268

This error is raised when you try to mass-assign a parameter hash that contains unpermitted keys. Your job_params method returns a hash containing only the key/values specified in the permit call so everything should be fine...

Are you sure that the error happens in the posted code segment? The only possible location would be the line @job = Job.new(job_params), is this line mentioned in the backtrace? If not, could you please post the complete backtrace? Because the error then must happen in a filter or observer or something like that...

Upvotes: 0

ChrisBarthol
ChrisBarthol

Reputation: 4959

In your log file it shows the parameters the app is getting from the create:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"Ohq4lVqPVMpjzbZwCfJNYBL78TAcoC0WZLSmpCzMD3k=", "job"=>{"job_title"=>"Junior Rails Developer", "job_description"=>"A new position getig nsomethfins lansnana", "languages"=>["", "Rails", "Ruby"], "country_code"=>"AO", "job_type"=>"Full-Time", "job_salary"=>"30000", "job_level"=>"Junior"}, "commit"=>"Create Job"}

You need to first make sure each parameter is listed in your strong params definition. Then make sure each parameter is the right type.

:parameter          #accepts a single entry
:parameter => []    #accepts a hash
:paramters_attributes: [:firstattribute, :secondattribute]  #accepts nested parameters

Your languages parameter is showing as a hash in your log, but you only have :languages in your permitted parameters. Changing the parameter to accept hashes should solve the issue.

:languages => []

Also this blog post is helpful by showing some strong parameters by example: http://blog.sensible.io/2013/08/17/strong-parameters-by-example.html

Upvotes: 2

Related Questions