I m using cancan(1.6.10) with rails 4.0.0. I have a model called 'App'(not scoped) and a controller Admin::AppsController(its scoped. ie app/controllers/admin/apps_controller).
the controller code is as
class Admin::AppsController < ApplicationController before_filter :authenticate_user! load_and_authorize_resource class: App def index end #CRUD methods and some other custom methods ... private def app_params params.require(:app).permit(:name, :description, :author, :url_path, :validated, :active, :version) end end
I m getting error when i try to create a 'app'.
ActiveModel::ForbiddenAttributesError - ActiveModel::ForbiddenAttributesError: activemodel (4.0.0) lib/active_model/forbidden_attributes_protection.rb:21:in `sanitize_for_mass_assignment'
I added
before_filter do resource = controller_path.singularize.gsub('/', '_').to_sym method = "#{resource}_params" params[resource] &&= send(method) if respond_to?(method, true) end
as specified in https://github.com/ryanb/cancan/issues/835#issuecomment-18663815 but still getting the above error.
Using name spaces. Please try to change your code to this one below. I had same issue after @JiriKolarik suggested his solution to work with name spaces. I hope it helps.
before_filter do resource = controller_name.singularize.to_sym method = "#{resource}_params" params[resource] &&= send(method) if respond_to?(method, true) end
if you use this workflow
before_filter do resource = controller_path.singularize.gsub('/', '_').to_sym method = "#{resource}_params" params[resource] &&= send(method) if respond_to?(method, true) end
then your params method should look like this
def admin_app_params params.require(:admin_app).permit(:name, :description, :author, :url_path, :validated, :active, :version) end
The reason why, it's because form generators (form_form, simple_form) generate params with namespace_resource
So if you have Blog::Post, form generator will create params like this
{ "blog_post"=>{"title"=>"Post"}, "commit"=>"Create", "action"=>"create", "controller"=>"blog/posts", "locale"=>"en"}
And this is how before filter works:
before_filter do resource = controller_path.singularize.gsub('/', '_').to_sym # => 'blog/posts' => 'blog/post' => 'blog_post' => :blog_post method = "#{resource}_params" # => 'blog_post_params' params[resource] &&= send(method) if respond_to?(method, true) # => params[:blog_post] end
If you need read :blog_post from params, solution above will not work. If you need read :post from params, then this solution will not work, if your controller will be blog/post
cancan just does not work with the strong parameter. While there is a new gem cancancan which works well without any code change.