2012-10-06 33 views
17

Güçlü parametreler kullanan standart bir RESTful denetleyicim var. Ben Cancan en load_and_authorize_resource için basit çağrı eklediğinizde benim config/initializers yılındaCanCan load_and_authorize_resource tetikleyiciler Yasakla Özellikler

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 

ben testinde @attr

olarak tanımlanır

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

alacağınız dosyayı strong_parameters.rb

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

var

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

Testlerde, kullanıcı olarak oturum açmak ve onlara yönetici olmak için gerekli rolleri vermek için düzgün bir şekilde ayarlamamı sağladım. Neden bunun neden yasaklandığını açıklamıyorum. Eminim gözden kaçırdığım basit bir şey. Bu sorunu başka biri ile karşılaştı ve buna bir çözüm buldu?

cevap

19

Bunun nedeni, CanCan'ın bir ön_filter ile önceden yüklemediyseniz, istenen kaynak için kendi alıcı yöntemini kullanacağına inanıyorum. Yani kontrolöre bu ekleyebilir ve çalışması gerekir:

class UsersController < ApplicationController 
    before_filter :new_user, :only => [:new, :create] 

    load_and_authorize_resource 

    def new_user 
    @user = User.new(safe_params) 
    end 
end 

(Ve sonra düzenleme/güncelleme eylemleri için aynı şeyi.)

+0

ben de aynı sorunu yaşıyorum inanıyoruz. Çözümünüzü daha da açıklığa kavuşturmak ister misiniz? –

+6

Biraz zaman oldu ama bir şans vereceğim;) Hangi kısım size sorun veriyor? Temelde cancan'ın 'load_and_authorize_resource' adını verirseniz, güçlü parametreler geminin çalışmasını önleyen denetleyicinin adı verilen en "mantıksal" kaynağı yüklemeyi deneyecektir. Bu durumda, Kullanıcı, '@ user = User.new (params [: user])' ı oluşturmaya çalışacaktır. Ancak, strong_parameters, bu şekilde kitlesel atamaya izin vermeyecektir. @user instance değişkenini ayarlamak için bir 'before_filter 'kullanırsanız, CanCan sadece bunun yerine kullanır. Eğer 'before_filter ', strong_parameters ile uyumluysa, bir hata yapmamalı. –

+0

Ahhh Takdir! CanCan'ın "kendi alıcı yöntemini" nasıl kullandığını anlamıyordum ... ama bu şimdi çok anlam ifade ediyor. Tekrar teşekkürler! –

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

** before_filter ** 'da daha önce gelen büyük önem ** load_and_authorize_resource ** – Ger