3

我正在使用带有 rails 4.0.0 的 cancan(1.6.10)。我有一个名为“App”的模型(没有作用域)和一个控制器 Admin::AppsController(它的作用域。即 app/controllers/admin/apps_controller)。

控制器代码如下

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

当我尝试创建“应用程序”时出现错误。

ActiveModel::ForbiddenAttributesError - ActiveModel::ForbiddenAttributesError:
activemodel (4.0.0) lib/active_model/forbidden_attributes_protection.rb:21:in `sanitize_for_mass_assignment'

我添加了

before_filter do
  resource = controller_path.singularize.gsub('/', '_').to_sym
  method = "#{resource}_params"
  params[resource] &&= send(method) if respond_to?(method, true)
end

https://github.com/ryanb/cancan/issues/835#issuecomment-18663815中所述,但仍然出现上述错误。

4

3 回答 3

8

使用名称空间。请尝试将您的代码更改为下面的代码。在@JiriKolarik 建议他使用名称空间的解决方案后,我遇到了同样的问题。我希望它有所帮助。

  before_filter do
    resource = controller_name.singularize.to_sym
    method = "#{resource}_params"
    params[resource] &&= send(method) if respond_to?(method, true)
  end
于 2013-10-12T15:39:23.447 回答
3

如果您使用此工作流程

before_filter do
  resource = controller_path.singularize.gsub('/', '_').to_sym
  method = "#{resource}_params"
  params[resource] &&= send(method) if respond_to?(method, true)
end

那么你的 params 方法应该是这样的

  def admin_app_params
    params.require(:admin_app).permit(:name, :description, :author, :url_path, :validated, :active, :version)
  end

之所以如此,是因为表单生成器(form_form,simple_form)使用namespace_resource生成参数

因此,如果您有 Blog::Post,表单生成器将创建这样的参数

{ "blog_post"=>{"title"=>"Post"}, "commit"=>"Create", "action"=>"create", "controller"=>"blog/posts", "locale"=>"en"}

这就是过滤器之前的工作方式:

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

如果您需要从 params 阅读 :blog_post,上述解决方案将不起作用。如果您需要从 params 读取 :post,则此解决方案将不起作用,如果您的控制器将是 blog/post

于 2013-10-21T20:44:15.093 回答
2

cancan 只是不适用于 strong 参数。虽然有一个新的 gem cancancan可以在没有任何代码更改的情况下运行良好。

于 2014-06-11T23:27:36.823 回答