ruby on rails - cancancan - CanCan load_and_authorize_resource desencadena atributos prohibidos
roles rails (2)
Tengo un controlador RESTful estándar que usa parámetros fuertes.
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
En mi config/initializers
tengo el archivo strong_parameters.rb
ActiveRecord::Base.send(:include, ActiveModel::ForbiddenAttributesProtection)
Cuando agrego una llamada simple a load_and_authorize_resource
de CanCan obtengo
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 <top (required)>''
Donde @attr
en la prueba se define como
before(:each) do
@attr =
{
first_name: "John",
last_name: "Doe",
email: "[email protected]",
password: "foobar",
password_confirmation: "foobar"
}
end
En las pruebas lo tengo todo configurado correctamente para iniciar sesión en el usuario y asignarle los roles necesarios para ser administrador, así que sé que no es eso. No sé por qué esto hace que ForbiddenAttributes se dispare. Estoy seguro de que es algo simple que he pasado por alto. ¿Alguien más ha encontrado este problema y ha encontrado una solución?
Creo que esto se debe a que CanCan utilizará su propio método getter para el recurso solicitado si no lo carga previamente con un before_filter. Así que podrías agregar esto al controlador y debería funcionar:
class UsersController < ApplicationController
before_filter :new_user, :only => [:new, :create]
load_and_authorize_resource
def new_user
@user = User.new(safe_params)
end
end
(Y luego haga lo mismo para las acciones de edición / actualización).
before_filter do
params[:user] = safe_params
end
load_and_authorize_resource