2011-10-26 27 views
0

訪問僅當我運行上的一些動作一的before_filter,以檢查是否該用戶是CURRENT_USER。繞過的before_filter但是從不同的控制器/視圖

before_filter :correct_user, :only => [:edit, :update, :destroy] 

def update 
    @user = User.find(params[:id]) 
    if @user.update_attributes(params[:user]) 
    redirect_to current_user, :notice => "User updated!" 
    else 
    redirect_to current_user, :notice => "User not updated. waa waa." 
    end 
end 

private 
def correct_user 
    if current_user != @user   
    redirect_to root_url, :notice => "Cannot act on different user." 
    end 
end 

不知道這是做事情的最好方法,但它的工作原理(也許更好的做法是簡單地使用,而不是通過PARAMS發現@user CURRENT_USER?)

現在用戶的has_many照片,並在我的照片索引視圖中列出所有用戶的照片,並允許用戶將任何一張照片設置爲個人資料照片。用戶表有一個稱爲primary_photo_id,持有該ID列,我用的link_to設置此:

=link_to "Make this your profile photo", user_path(@user, :user => {:primary_photo_id => "#{photo.id}"}), :method => :put 

的問題是,在與踢的before_filter會阻止這樣做,因爲@user是通過params [:id]檢索失敗,因爲它不是正確的參數。如果我刪除了before_filter,它工作正常,但它不再檢查正確的用戶。

(第二有點相關的問題是,爲什麼上面的代碼工作,但此一:。

=link_to "Make this your profile photo", user_path(@user, :primary_photo_id => "#{photo.id}"), :method => :put 

謝謝,我很新的軌道和程序,所以,只要你能說關於我的具體問題,任何不好的做法,我在這裏的代碼做的,是非常讚賞。

回答

2

過濾器(#correct_user)上運行的前#update之前,讓你的實例變量@user尚未設定時如果在第一次過濾之前沒有將其設置在另一個過濾器中,則將它與過濾器進行比較。你的執行順序是這樣的:

  1. 運行#correct_user - 比較CURRENT_USER到@user(如果未設置,這是無)。這些將只匹配,如果用戶沒有我猜
  2. 假設我們把它通過登錄,運行#UPDATE並期待@user

也許最簡單的方法來解決你的問題僅僅是移動@user查找到前過濾:

before_filter :correct_user, :only => [:edit, :update, :destroy] 

def edit 
    # .. as before, but no need to look up user first 
end 

def update 
    if @user.update_attributes(params[:user]) 
    redirect_to current_user, :notice => "User updated!" 
    else 
    redirect_to current_user, :notice => "User not updated. waa waa." 
    end 
end 

def destroy 
    # .. as before, but no need to look up user first 
end 

private 

def correct_user 
    @user = User.find(params[:id]) 
    if current_user != @user   
    redirect_to root_url, :notice => "Cannot act on different user." 
    end 
end 

由於@user現在正在位於過濾器,也沒有必要在每個控制器的行動再次查找。希望這可以幫助!

+0

這個偉大的工作。謝謝馬特!我實際上決定使用兩個before_filters,第一個用於get_user,另一個用於檢查用戶是否正確。儘管它可能不那麼「乾燥」,但對我來說有點清晰。而不是使用用戶= User.find(PARAMS [:編號]),我也可以做用戶= CURRENT_USER(因爲有一個輔助方法來獲取會話的用戶)..這是一般建議,特別是對,比方說,編輯,更新,以及其他任何人都無法做到的事情,除了登錄用戶? – kindofgreat

+0

是啊,頻繁的那種狀態,我會成立之前,我的過濾器,這樣就計算出,如果用戶是管理員,如果這樣將允許來自PARAMS設置,否則硬線連接到登錄的用戶。就像'@user = current_user.admin? ? User.find(params [:id]):current_user'。 如果您沒有管理的情況下,我只是將它設置爲直接CURRENT_USER,因爲你可能已經有一個用戶對象實例化,這樣做的另一個查詢是沒有意義的。 –

相關問題