Tengo un controlador RESTful estándar que usa parámetros potentes.CanCan load_and_authorize_resource triggers Forbidden Attributes
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 simple llamada a load_and_authorize_resource
de CanCan consigo
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)>'
Dónde @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 darles los roles necesarios para ser administrador, así que sé que no es eso. No sé por qué esto está provocando la activación de ForbiddenAttributes. 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 estoy teniendo el mismo problema. ¿Te importaría clarificar tu solución más? –
Ha pasado un tiempo, pero lo intentaré;) ¿Qué parte te está causando problemas? Básicamente, si llama a 'load_and_authorize_resource' de cancan, intentará cargar el recurso más" lógico "dado el nombre del controlador, que precede a la operación de la gema de los parámetros fuertes. En este caso, intentará compilar el usuario, '@user = User.new (params [: user])' Pero los strong_parameters no permitirán la asignación masiva de esta manera. Si usa un 'before_filter' para establecer la variable de instancia @user, CanCan simplemente usará eso en su lugar. Si su 'before_filter' cumple con strong_parameters, no debería generar un error. –
Ahhh ¡Muy apreciado! No entendía cómo CanCan estaba "... [usando] su propio método getter ..." pero eso tiene mucho sentido ahora. ¡Gracias de nuevo! –