Strong Attributes exception in rails 3. No idea whats causing it
-
21-12-2019 - |
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'
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