【问题标题】:Mass-Assignment Roles issue in controller spec控制器规范中的批量分配角色问题
【发布时间】:2013-01-17 16:51:36
【问题描述】:

我正在使用 Devise 开发一个应用程序。 因为我需要一个 UI 来管理用户,所以我还生成了一个控制器和关联的视图来对 User 模型执行所有 CRUD 操作。

然后我创建一个“角色”字段,用于 CanCan 并作为批量分配角色。

现在我正在尝试正确地制作所有规格,我有这个测试

describe "POST create" do
  describe "with valid params" do
    it "creates a new User" do
      expect {
        post :create, {:user => valid_attributes}
      }.to change(User, :count).by(1)
    end
    # ...
  end
end

执行时引发:

UsersController POST create with valid params creates a new User
Failure/Error: post :create, {:user => valid_attributes}
ActiveModel::MassAssignmentSecurity::Error:
   Can't mass-assign protected attributes: name, surname, role
 # ./spec/controllers/users_controller_spec.rb:62:in `block (5 levels) in <top (required)>'
 # ./spec/controllers/users_controller_spec.rb:61:in `block (4 levels) in <top (required)>'

我的控制器的#create 方法定义为 类用户控制器

  # GET /users
  # GET /users.json
  def index
    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @users }
    end
  end

  # GET /users/1
  # GET /users/1.json
  def show
    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @user }
    end
  end

  # GET /users/new
  # GET /users/new.json
  def new
    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @user }
    end
  end

  # GET /users/1/edit
  def edit
  end

  # POST /users
  # POST /users.json
  def create
    @user = User.new params[:user], :as => current_user.role.to_sym
    respond_to do |format|
      if @user.save
        format.html { redirect_to @user, notice: 'Utente creato con successo.' }
        format.json { render json: @user, status: :created, location: @user }
      else
        format.html { render action: "new" }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end

  # PUT /users/1
  # PUT /users/1.json
  def update
    respond_to do |format|
     if @user.update_attributes(params[:user], :as => current_user.role.to_sym)
       format.html { redirect_to @user, notice: 'Profilo aggiornato con successo.' }
       format.json { head :no_content }
      else
       format.html { render action: "edit" }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end

 # DELETE /users/1
  # DELETE /users/1.json
  def destroy
    @user.destroy

    respond_to do |format|
      format.html { redirect_to users_url }
      format.json { head :no_content }
    end
  end
end

为了使 rspec 与 Devise 一起正常运行,我遵循了 the official doc 并且我还创建了宏(与那里描述的相同),除了我没有两个不同的 FactoryGirl 而是一个我在创建角色时定义的位置,例如:

FactoryGirl.create(:user, role: :admin) # or role: :user

这是用户模型

class User < ActiveRecord::Base
  attr_accessible :email, :password, :password_confirmation, :remember_me
  attr_accessible :email, :password, :password_confirmation, :remember_me, :name, :surname, :role, :as => :admin

  devise :database_authenticatable, :recoverable, :rememberable, :trackable,
         :validatable

  VALID_ROLES = [:admin, :student]

  validates_inclusion_of :role, in: VALID_ROLES

  def is_admin?
    role == "admin"
  end

  def is_student?
    role == "student"
  end
end

我该如何解决这个问题?我花了一整天的时间,但我无法正常工作:-(

【问题讨论】:

    标签: ruby-on-rails rspec devise tdd


    【解决方案1】:

    这个问题是由 cancan 的 load_and_authorize_resource 引起的,它调用 User.create 却不允许我声明包含角色的 ":as" 子句。

    修复实际上是删除对load_and_authorize_resource 的调用,并以典型的方式创建资源(就像没有 cancan 一样)。然后在每个方法中调用授权检查,即authorize! :create, User for #create。

    可能它也可以通过使用load_and_authorize_resource :except =&gt; [:create] 之类的东西来工作,然后只在那里手动执行,但我不确定,我没有测试它。

    顺便说一句,我在这个错误上浪费了一个工作日,我真的希望这可以帮助遇到同样问题的其他人。

    【讨论】:

      【解决方案2】:

      自 Rails 3.2 版以来,已经实现了安全性。 要修复您的错误,请将以下行添加到您的用户模型中:

      attr_accessible :name, :surname, :role
      

      有关更多详细信息,请阅读本指南:http://guides.rubyonrails.org/security.html

      【讨论】:

      • 嗨,对不起。我忘了把用户模型放在 OP 上。我现在已经编辑过了。我知道我必须声明 attr_accessible,这就是我遇到问题的地方......我正在尝试使用批量分配角色。
      【解决方案3】:

      您在 de 'post' 行中输入了错误的用户。改变这个:

      post :create, {:user => valid_attributes}
      

      到这里:

      post :create, :user => {valid_attributes}
      

      我假设您的变量 'valid_attributes' 是具有该类属性的哈希。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-14
        • 2012-04-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-09
        • 1970-01-01
        • 2013-07-26
        相关资源
        最近更新 更多