2011-06-05 29 views
2

我是Ruby-on-Rails的新手。在環顧本網站和康康指南後,我可以使用一些幫助。我很難讓它在Cancan和Devise上運行。用戶(設計)只有價格,所以價格屬於用戶。如何設置當前用戶ID只能使用自己的動作

我有我的數據庫中爲user_id爲我的價格遷移:

create_table "prices", :force => true do |t| 
    t.string "price_name" 
    t.decimal "price" 
    t.date  "date" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    t.integer "user_id" 
    end 

我的價格控制器(一切都是腳手架,但是這是從另一個遷移分離到的價格表中USER_ID):

class PricesController < ApplicationController 
    before_filter :authenticate_user! 



    # GET /prices 
    # GET /prices.xml 
    def index 
    @prices = Price.all 

    respond_to do |format| 
     format.html # index.html.erb 
     format.xml { render :xml => @prices } 
    end 
    end 

    # GET /prices/1 
    # GET /prices/1.xml 
    def show 
    @price = Price.find(params[:id]) 

    respond_to do |format| 
     format.html # show.html.erb 
     format.xml { render :xml => @price } 
    end 
    end 

    # GET /prices/new 
    # GET /prices/new.xml 
    def new 
    @price = Price.new 

    respond_to do |format| 
     format.html # new.html.erb 
     format.xml { render :xml => @price } 
    end 
    end 

    # GET /prices/1/edit 
    def edit 
    @price = Price.find(params[:id]) 
    end 

    # POST /prices 
    # POST /prices.xml 
    def create 
    @price = current_user.prices.build(params[:price]) 

    respond_to do |format| 
     if @price.save 
     format.html { redirect_to(@price, :notice => 'Price was successfully created.') } 
     format.xml { render :xml => @price, :status => :created, :location => @price } 
     else 
     format.html { render :action => "new" } 
     format.xml { render :xml => @price.errors, :status => :unprocessable_entity } 
     end 
    end 
    end 

    # PUT /prices/1 
    # PUT /prices/1.xml 
    def update 
    @price = Price.find(params[:id]) 

    respond_to do |format| 
     if @price.update_attributes(params[:price]) 
     format.html { redirect_to(@price, :notice => 'Price was successfully updated.') } 
     format.xml { head :ok } 
     else 
     format.html { render :action => "edit" } 
     format.xml { render :xml => @price.errors, :status => :unprocessable_entity } 
     end 
    end 
    end 

    # DELETE /prices/1 
    # DELETE /prices/1.xml 
    def destroy 
    @price = Price.find(params[:id]) 
    @price.destroy 

    respond_to do |format| 
     format.html { redirect_to(prices_url) } 
     format.xml { head :ok } 
    end 
    end 
end 

然後這是我ability.rb(應用程序/模型/ ability.rb):

class Ability 
    include CanCan::Ability 

    def initialize(user) 
    user ||= User.new 
    if user.admin? 
     can :manage, :all 
     cannot :destroy, User, :id => current_user.id 
    else 
     can :manage, Price, :user_id => user.id 
    end 
    end 
end 

我的問題是,我該如何使它只有當前用戶可以編輯或刪除他或她自己的價格?我的代碼不斷讓任何登錄的用戶根據任何人的價格做任何事情。

謝謝先進。

更新代碼的工作原理:

class Ability 
    include CanCan::Ability 

    def initialize(user) 
    user ||= User.new 
    can :manage, Price, :user_id => user.id 
    end 
end 

重要* - 刪除(或註釋掉)編輯,更新,破壞,創造和新的實例變量(如@),我想知道爲什麼我的代碼沒有工作,我刪除了下面,它做到了:

def new 
    # @price = Price.new 
def edit 
    # @price = Price.find(params[:id]) 
def create 
    # @price = Price.new(params[:price]) or @price = current_user.prices.build(params[:price]) 
def update 
    # @price = Price.find(params[:id]) 
def destroy 
    # @price = Price.find(params[:id]) 

然後在PricesController的頂部:

class PricesController < ApplicationController 
    before_filter :authenticate_user! 
    load_and_authorize_resource 
    skip_authorize_resource :only => :show 

回答

3

您已經定義了您的權限,但您還必須在控制器和可能的視圖中檢查它們以執行它們。

indexshow動作,例如:

def index 
    # Check if the current user can actually see the Price index. 
    authorize! :index, Price 

    @prices = Price.all 

    # ... 
end 

def show 
    @price = Price.find params[:id] 

    # Check if the current user can actually see the Price. 
    authorize! :show, @price 

    # ... 
end 

正如你可以看到,呼叫遵循格式authorize! :action, object,其中object可以是類本身或者它的一個實例。當你有一個可用時,你應該使用後者。

爲了簡單起見,你可以加入這一行的地方在你的控制器:

authorize_resource 

,它會自動對每個動作做authorize! params[:action], @price || Price@price || Price成語表示@price將被使用,除非它是nil,在這種情況下Price將被使用。

此外,請記住,如果當前用戶沒有所需的權限,對authorize!的調用將引發CanCan::AccessDenied異常。你應該從這個例外ApplicationController營救:在康康舞維基

rescue_from CanCan::AccessDenied do |exception| 
    redirect_to root_url, :alert => exception.message 
end 

退房的Authorizing Controller Actions更詳細的信息。

+0

好的,而不是authorize_resource我把load_and_authorize_resource和刪除@Price行動以及讓它工作。謝謝你的支持! – LearningRoR 2011-06-05 19:59:08

1

嘗試將一個before_filter放入您的控制器中,並確保用戶可以做出感興趣的事情。這可以保護後端。

然後還可以使用cancan權限隱藏或以其他方式在視覺上保護前端數據。