Question

Been stuck on this for a few days now. Any help would be much appreciated. I have a form that sends an artist name to a create controller. The create controller creates the artist with the name, assigns a user to that artist, and creates an artist layout. I think i have added the correct whitelisting for the strong params gem, however i get the the below error.

Error:

ActiveModel::ForbiddenAttributes in ArtistsController#create

ActiveModel::ForbiddenAttributes
Rails.root: /sites/music3

Application Trace | Framework Trace | Full Trace
Request

Parameters:

{"utf8"=>"✓",
 "authenticity_token"=>"xxxxxxxxxxxxxxxxxxxxxx",
 "artist"=>{"name"=>"kkkk"},
 "commit"=>"Create Artist"}
Show session dump

Show env dump

Response

Headers:

Controller

def create

@artist = Artist.new(artist_create_params)
#assigns User

@user = current_user
@artist.users << @user

@form = render_to_string('artists/_form',:layout => false)

#creates and assigns layout
@artist.profile_layout = ProfileLayout.new

respond_to do |format|
  if @artist.update_attributes(artist_create_params)
    format.html { redirect_to(edit_artist_path(@artist.url_slug)) }
    format.xml { render :xml => @artist, :status => :created, :location => @artist }

  else
    format.html { render :action => "new" }
    format.xml { render :xml => @artist.errors, :status => :unprocessable_entity }
  end
end
end

def artist_create_params
   #Using `strong_parameters` gem
   params.required(:commit).permit!
   params.required(:artist).permit!

end

I'm allowing all params to be past through (params!) as I was trying to identify what was throwing the error. However I would like to whitelist specific params once I figure out what the problem is.

Strong parameters is working in other places. Its just giving me problems on create. Any help would be appreciated

Thanks in advance. Ted.


Update:

Initializer:

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

Changed to

def artist_create_params
  # NOTE: Using `strong_parameters` gem

    params.require(:artist).permit(:name)

end

Still getting above error. Doesn't show the line the error is occuring on. See below

Started POST "/artists" for 127.0.0.1 at 2014-06-04 19:10:27 -0400

Processing by ArtistsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"xxxxxxxxxxxxx", "artist"=>{"name"=>"ffasdf"}, "commit"=>"Create Artist"}
Completed 500 Internal Server Error in 8ms

ActiveModel::ForbiddenAttributes (ActiveModel::ForbiddenAttributes):
  strong_parameters (0.2.3) lib/active_model/forbidden_attributes_protection.rb:11:in `sanitize_for_mass_assignment'
  activerecord (3.2.11) lib/active_record/attribute_assignment.rb:75:in `assign_attributes'
  activerecord (3.2.11) lib/active_record/base.rb:497:in `initialize'
  cancan (1.6.8) lib/cancan/controller_resource.rb:85:in `new'
  cancan (1.6.8) lib/cancan/controller_resource.rb:85:in `build_resource'
  cancan (1.6.8) lib/cancan/controller_resource.rb:66:in `load_resource_instance'
  cancan (1.6.8) lib/cancan/controller_resource.rb:32:in `load_resource'
  cancan (1.6.8) lib/cancan/controller_resource.rb:25:in `load_and_authorize_resource'
  cancan (1.6.8) lib/cancan/controller_resource.rb:10:in `block in add_before_filter'
  activesupport (3.2.11) lib/active_support/callbacks.rb:440:in `_run__3264816457187544022__process_action__2854128236876807797__callbacks'
  activesupport (3.2.11) lib/active_support/callbacks.rb:405:in `__run_callback'
  activesupport (3.2.11) lib/active_support/callbacks.rb:385:in `_run_process_action_callbacks'
  activesupport (3.2.11) lib/active_support/callbacks.rb:81:in `run_callbacks'
  actionpack (3.2.11) lib/abstract_controller/callbacks.rb:17:in `process_action'
  actionpack (3.2.11) lib/action_controller/metal/rescue.rb:29:in `process_action'
  actionpack (3.2.11) lib/action_controller/metal/instrumentation.rb:30:in `block in process_action'
  activesupport (3.2.11) lib/active_support/notifications.rb:123:in `block in instrument'
  activesupport (3.2.11) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
  activesupport (3.2.11) lib/active_support/notifications.rb:123:in `instrument'
  actionpack (3.2.11) lib/action_controller/metal/instrumentation.rb:29:in `process_action'
  actionpack (3.2.11) lib/action_controller/metal/params_wrapper.rb:207:in `process_action'
  activerecord (3.2.11) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
  actionpack (3.2.11) lib/abstract_controller/base.rb:121:in `process'
  actionpack (3.2.11) lib/abstract_controller/rendering.rb:45:in `process'
  actionpack (3.2.11) lib/action_controller/metal.rb:203:in `dispatch'
  actionpack (3.2.11) lib/action_controller/metal/rack_delegation.rb:14:in `dispatch'
  actionpack (3.2.11) lib/action_controller/metal.rb:246:in `block in action'
  actionpack (3.2.11) lib/action_dispatch/routing/route_set.rb:73:in `call'
  actionpack (3.2.11) lib/action_dispatch/routing/route_set.rb:73:in `dispatch'
  actionpack (3.2.11) lib/action_dispatch/routing/route_set.rb:36:in `call'
  journey (1.0.4) lib/journey/router.rb:68:in `block in call'
  journey (1.0.4) lib/journey/router.rb:56:in `each'
  journey (1.0.4) lib/journey/router.rb:56:in `call'
  actionpack (3.2.11) lib/action_dispatch/routing/route_set.rb:601:in `call'
  warden (1.2.1) lib/warden/manager.rb:35:in `block in call'
  warden (1.2.1) lib/warden/manager.rb:34:in `catch'
  warden (1.2.1) lib/warden/manager.rb:34:in `call'
  client_side_validations (3.2.5) lib/client_side_validations/middleware.rb:21:in `call'
  actionpack (3.2.11) lib/action_dispatch/middleware/best_standards_support.rb:17:in `call'
  rack (1.4.3) lib/rack/etag.rb:23:in `call'
  rack (1.4.3) lib/rack/conditionalget.rb:35:in `call'
  actionpack (3.2.11) lib/action_dispatch/middleware/head.rb:14:in `call'
  actionpack (3.2.11) lib/action_dispatch/middleware/params_parser.rb:21:in `call'
  actionpack (3.2.11) lib/action_dispatch/middleware/flash.rb:242:in `call'
  rack (1.4.3) lib/rack/session/abstract/id.rb:210:in `context'
  rack (1.4.3) lib/rack/session/abstract/id.rb:205:in `call'
  actionpack (3.2.11) lib/action_dispatch/middleware/cookies.rb:341:in `call'
  activerecord (3.2.11) lib/active_record/query_cache.rb:64:in `call'
  activerecord (3.2.11) lib/active_record/connection_adapters/abstract/connection_pool.rb:479:in `call'
  actionpack (3.2.11) lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'
  activesupport (3.2.11) lib/active_support/callbacks.rb:405:in `_run__1232201288606729007__call__1474813276301895872__callbacks'
  activesupport (3.2.11) lib/active_support/callbacks.rb:405:in `__run_callback'
  activesupport (3.2.11) lib/active_support/callbacks.rb:385:in `_run_call_callbacks'
  activesupport (3.2.11) lib/active_support/callbacks.rb:81:in `run_callbacks'
  actionpack (3.2.11) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
  actionpack (3.2.11) lib/action_dispatch/middleware/reloader.rb:65:in `call'
  actionpack (3.2.11) lib/action_dispatch/middleware/remote_ip.rb:31:in `call'
  actionpack (3.2.11) lib/action_dispatch/middleware/debug_exceptions.rb:16:in `call'
  actionpack (3.2.11) lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'
  railties (3.2.11) lib/rails/rack/logger.rb:32:in `call_app'
  railties (3.2.11) lib/rails/rack/logger.rb:18:in `call'
  actionpack (3.2.11) lib/action_dispatch/middleware/request_id.rb:22:in `call'
  rack (1.4.3) lib/rack/methodoverride.rb:21:in `call'
  rack (1.4.3) lib/rack/runtime.rb:17:in `call'
  activesupport (3.2.11) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
  rack (1.4.3) lib/rack/lock.rb:15:in `call'
  actionpack (3.2.11) lib/action_dispatch/middleware/static.rb:62:in `call'
  railties (3.2.11) lib/rails/engine.rb:479:in `call'
  railties (3.2.11) lib/rails/application.rb:223:in `call'
  rack (1.4.3) lib/rack/content_length.rb:14:in `call'
  railties (3.2.11) lib/rails/rack/log_tailer.rb:17:in `call'
  rack (1.4.3) lib/rack/handler/webrick.rb:59:in `service'
  /Users/therealtedkennedy/.rvm/rubies/ruby-1.9.2-p320/lib/ruby/1.9.1/webrick/httpserver.rb:111:in `service'
  /Users/therealtedkennedy/.rvm/rubies/ruby-1.9.2-p320/lib/ruby/1.9.1/webrick/httpserver.rb:70:in `run'
  /Users/therealtedkennedy/.rvm/rubies/ruby-1.9.2-p320/lib/ruby/1.9.1/webrick/server.rb:183:in `block in start_thread'
Was it helpful?

Solution

Based on the stack trace, it looks like the assignment that triggers the error is coming from cancan, not from setting the artist's name. Try temporarily disabling the before_filter that uses cancan and see whether that resolves the issue. If it does, then you need to re-enable it, dig into cancan and figure out how to make it play nicely with strong_parameters. I don't use it myself, but I think there's a fork for Rails 4 called cancancan, which might work with rails 3.2 and strong_parameters as well.

Unrelated to your immediate problem, but you should probably also look at upgrading to the latest version in the Rails 3.2.x series to pick up the different security fixes they've released.

OTHER TIPS

You don't need to permit the :commit params because you aren't trying to mass assign them to anything. Just use:

params.require(:artist).permit!

Or even better:

params.require(:artist).permit(:name)

That said, I'm surprised you're getting the error you say, so fix that and report back.

Skipping the cancan authorization defeats the purpose of having cancan.

This is what I did:

Switch to CanCanCan

As per the CanCanCan docs:

This repo is a continuation of the dead CanCan project. Our mission is to keep CanCan alive and moving forward, with maintenance fixes and new features.

CanCanCan also supports Strong Parameters out of the box.

Create Private Methods for create_params or update_params

As per docs, create private methods in your controllers to handle attribute permissions:

private

def create_params
  params.require(:speaking_lesson).permit(:name, :description, exercises_attributes: [:text])
end

And then you'll have access an instance of the new model for use, in your create method:

def create
  # @speaking_lesson is automatically created by CanCanCan during load_and_authorize_resource
  @speaking_lesson.user_id = current_user.id

  ... do other stuff ...
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top