Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 369
Shaun Frost Duke Jackson Avatar asked Dec 17 '13 22:12

Shaun Frost Duke Jackson


2 Answers

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

like image 71
ChrisBarthol Avatar answered Nov 15 '22 10:11

ChrisBarthol


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.

like image 21
RubyNewby Avatar answered Nov 15 '22 09:11

RubyNewby