我正在使用Devise开发一个应用程序。 由于我需要一个用户界面来管理用户,我还生成了一个控制器和相关的视图,以便在用户模型上执行所有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方法被定义为 class UsersController&lt; ApplicationController的 load_and_authorize_resource
# 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
我该如何解决?这花了我一整天,我无法做到这一点: - (
答案 0 :(得分:1)
问题是由cancan的load_and_authorize_resource
引起的,User.create
正在调用load_and_authorize_resource
而不允许我声明包含该角色的“:as”子句。
修复实际上是删除对authorize! :create, User
的调用并以典型方式创建资源(就像没有cancan一样)。然后在每个方法中调用授权检查,即#{1}}为#create。
也许它可以通过使用类似load_and_authorize_resource :except => [:create]
之类的东西来工作,然后只在那里手动完成,但我不确定,我没有测试它。
顺便说一句,我在这个bug上失去了一个工作日,我真的希望这可以帮助其他人解决同样的问题。
答案 1 :(得分:0)
自Rails版本3.2以来,已经实现了安全性。 要修复错误,请在用户模型中添加以下行:
attr_accessible :name, :surname, :role
有关详细信息,请参阅本指南:http://guides.rubyonrails.org/security.html
答案 2 :(得分:0)
你让de'post'行的用户出错了。改变这个:
post :create, {:user => valid_attributes}
到此:
post :create, :user => {valid_attributes}
我假设你的变量'valid_attributes'是一个带有该类属性的哈希。