CanCan load_and_authorize_resource触发禁止的属性

我有一个使用强参数的标准RESTful控制器。

class UsersController < ApplicationController respond_to :html, :js def index @users = User.all end def show @user = User.find(params[:id]) end def new @user = User.new end def edit @user = User.find(params[:id]) end def create @user = User.new(safe_params) if @user.save redirect_to @user, notice: t('users.controller.create.success') else render :new end end def update @user = User.find(params[:id]) if @user.update_attributes(safe_params) redirect_to @user, notice: t('users.controller.update.success') else render :edit end end def destroy @user = User.find(params[:id]) if current_user != @user @user.destroy else flash[:error] = t('users.controller.destroy.prevent_self_destroy') end redirect_to users_url end private def safe_params safe_attributes = [ :first_name, :last_name, :email, :password, :password_confirmation, ] if current_user.is?(:admin) safe_attributes += [:role_ids] end params.require(:user).permit(*safe_attributes) end end 

在我的config/initializers我有文件strong_parameters.rb

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

当我向CanCan的load_and_authorize_resource添加一个简单的调用时,我得到了

 1) UsersController POST create with invalid params re-renders the 'new' template Failure/Error: post :create, user: @attr ActiveModel::ForbiddenAttributes: ActiveModel::ForbiddenAttributes # ./spec/controllers/users_controller_spec.rb:128:in `block (4 levels) in ' 

其中@attr中的@attr定义为

  before(:each) do @attr = { first_name: "John", last_name: "Doe", email: "user@example.com", password: "foobar", password_confirmation: "foobar" } end 

在测试中,我已正确设置以登录用户并为他们提供管理员所需的角色,因此我知道不是这样。 我不知道为什么这会导致ForbiddenAttributes触发。 我确信这是我忽略的简单事情。 有没有其他人遇到过这个问题并找到了解决方案呢?

我相信这是因为如果您没有使用before_filter预加载它,CanCan将为所请求的资源使用自己的getter方法。 所以你可以将它添加到控制器,它应该工作:

 class UsersController < ApplicationController before_filter :new_user, :only => [:new, :create] load_and_authorize_resource def new_user @user = User.new(safe_params) end end 

(然后对编辑/更新操作执行相同操作。)

 before_filter do params[:user] = safe_params end load_and_authorize_resource