2011-03-02 71 views
3

作爲新手ROR開發者,我一直在想辦法保護某些方法,以確保正確的用戶更新他們自己的內容。這是我的方法的一個例子。保護方法的好習慣

你會推薦一個更清潔的方式或更好的方式來完成這樣的任務嗎?

# Example Controller 
class Owner::PropertiesController < Owner::BaseController 

    def index 
    end 

    etc..... 

    def update 
    @property = Property.find(params[:id]) 

    # Check correct owner 
    check_owner(:owner_id => @property.owner_id) 

    if @property.update_attributes(params[:property]) 
     redirect_to([:owner, @property], :notice => 'Property was successfully updated.') 
    else 
     render :action => "edit" 
    end 

    end 

    def destroy 
    @property = Property.find(params[:id]) 

    # Check correct owner 
    check_owner(:owner_id => @property.owner_id) 

    @property.destroy 
    redirect_to(owner_properties_url) 
    end 

    private 

    def check_owner p = {} 
    if p[:owner_id] != session[:owner_id] 
     redirect_to([:owner, @property], :notice => "Property not found.") 
    end 
    end 

回答

0

您可以使用像declarative_authorization這樣的寶石來做到這一點。如果你想自己做,我會建議乾脆曬你的代碼一點點:

class Owner::PropertiesController < Owner::BaseController 
    before_filter :check_owner, :only => [:update, :destroy] 

    def update 
    if @property.update_attributes(params[:property]) 
     redirect_to([:owner, @property], :notice => 'Property was successfully updated.') 
    else 
     render :action => "edit" 
    end 
    end 

    def destroy 
    @property.destroy 
    redirect_to(owner_properties_url) 
    end 

    private 

    def check_owner 
    @property = Property.find(params[:id] 

    if @property.owner_id != session[:owner_id] 
     redirect_to([:owner, @property], :notice => "Property not found.") and return 
    end 
    end 
end 

此外,您可以通過所有者篩選屬性,以確保誰是不是所有者不能與交互的用戶屬性不是他/她的。例如:

def update 
    @owner = Owner.find(session[:owner_id]) 
    @property = @owner.properties.find(params[:id]) 
    redirect_to unauthorized_page and return if @property.nil? 
end 

這將迫使您正在搜索是屬於會話的那些屬性[:owner_id],而不是性質的整個宇宙。這意味着會話[:owner_id]不擁有的屬性甚至不會被考慮。然後,您可以將此代碼放入before_filter中,以便它可以在多個操作中重用。

+0

感謝您的所有評論。我更喜歡保持乾燥,這很好。我不想因爲擁有許多寶石而混亂,所以只需使用並通過過濾器傳遞屬性就是完美的。 TY – Lee 2011-03-02 00:48:46

0

考慮使用所討論的技術here

僅在您的用戶模型和查詢屬性內通過該關聯添加關聯。

property = Property.find(params[:id]) 
# vs 
property = current_user.properties.find(params[:id]) 
4

這是這樣做的一種方式,雖然有點笨拙的國際海事組織。我傾向於採取以下方法在這些情況下:

class FoosController < ApplicationController 
    before_filter :find_user 

    def create 
    @foo = @user.foos.build 
    end 

    def update 
    @foo = @user.foos.find(params[:id]) 
    end 

    private 

    def find_user 
    @user = User.find(session[:current_user_id]) 
    end 
end 

這是一個很大清潔劑,以及意圖非常明顯:你只在試圖找到一個Foo屬於@user感興趣。這種方法的缺點之一是,如果所有權規則發生變化,則需要一些工作來改變它,但我發現它對我來說合理地合理。