2012-10-06 2 views
17

강력한 매개 변수를 사용하는 표준 RESTful 컨트롤러가 있습니다. 나는 캉캉의 load_and_authorize_resource에 간단한 전화를 추가 할 때 내 config/initializers에서CanCan load_and_authorize_resource 트리거 금지 된 속성

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 

나는 시험에 @attr

으로 정의된다

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)>' 

를 얻을 파일 strong_parameters.rb

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

before(:each) do 
    @attr = 
     { 
     first_name: "John", 
     last_name: "Doe", 
     email: "[email protected]", 
     password: "foobar", 
     password_confirmation: "foobar" 
     } 
    end 

테스트에서 나는 사용자를 로그인하고 관리자가되기 위해 필요한 역할을하기 위해 모든 설정을 올바르게했습니다. 왜 이것이 ForbiddenAttributes를 유발하는지 알 수 없습니다. 나는 그것이 간과 한 간단한 것이라고 확신합니다. 다른 누구와도이 문제가 발생하여 해결 방법을 찾았습니까?

답변

19

CanCan은 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 

을 (그리고 편집/업데이트 작업에 대해 동일한 않습니다.)

+0

내가 같은 문제가 발생하고 생각합니다. 당신의 솔루션을 더 명확히 해줄 수 있습니까? –

+6

잠시 지났지 만 나는 한 발을 내줄거야;) 어떤 부분이 문제가 되는가? 기본적으로 cancan의'load_and_authorize_resource'를 호출하면 강력한 매개 변수 gem의 연산에 앞서 컨트롤러의 이름이 주어지면 가장 "논리적 인"리소스를로드하려고 시도합니다. 이 경우에 그것은 사용자,'@user = User.new (params [: user])'를 만들려고 시도 할 것입니다. 그러나 strong_parameters는 이런 식으로 대량 할당을 허용하지 않습니다. 'before_filter'를 사용하여 @user 인스턴스 변수를 설정하면 CanCan은 대신에 그것을 사용할 것입니다. 'before_filter'가 strong_parameters를 따르는 경우 오류가 발생해서는 안됩니다. –

+0

아, 감사합니다! CanCan이 "... 자체 getter 메소드를 사용하여 ..."하는 방법을 이해하지 못했습니다.하지만 이제는 많은 의미가 있습니다. 다시 한 번 감사드립니다! –

7
before_filter do 
    params[:user] = safe_params 
end 
load_and_authorize_resource 
+1

** before_filter **에 대한 주요 강조 사항 ** load_and_authorize_resource ** – Ger