2012-02-26 22 views
0

尋找在Rails模型中進行所有權驗證而不會膨脹我的控制器的最佳方式。這意味着我需要以某種方式將current_user傳遞給模型。瞭解Rails模型的類屬性的生存期

我目前設置的用戶模型中的類屬性的CURRENT_USER在每個請求的開頭:

class User < ActiveRecord::Base 
    cattr_accessor :current_user 
end 

class ApplicationController < ActionController::Base 
    before_filter :set_current_user 
    def set_current_user 
    User.current_user = current_user 
    end 
end 

我不知道如果我完全理解User.current_user在這個壽命場景。請求期間價值可能會發生變化嗎?

我主要想知道上述是否安全使用,以及是否有更好的方法。

+0

取決於您是否在多線程模式下運行您的應用程序 – 2012-02-26 07:07:02

回答

2

要回答你的問題的第一部分。該屬性將被保存在內存中,直到User-class被刷新/發送到垃圾收集器。這通常是在虛擬機或解釋器關閉時。

在像Heroku這樣的環境中,這個變量可以存儲在請求之間,一個未經身份驗證的用戶可以通過訪問這個變量來訪問最近的用戶,除非當第一個用戶完成時它被清除。

+0

除了當未經身份驗證的用戶訪問時,它將被設置爲零 – tybro0103 2012-02-26 03:28:56

+0

我有一個完全不同的問題,似乎是由這個問題。你能否提供任何參考文獻來討論在Heroku的請求之間變量如何保存在內存中? – 2012-06-26 23:35:06

1

如果您想要符合最佳實踐,這絕對是正確的方法。 current_user是一種控制器方法,通過遵循Chain-of-responsibility模式,User模型不應該知道當前用戶是誰。

+1

您說這很有趣,因爲OP *是*告訴用戶模型存儲當前用戶是誰。 – 2012-02-26 02:32:04

+0

謝謝......雖然......我更關心一生......在請求期間價值可能會發生變化嗎? – tybro0103 2012-02-26 02:43:21

+0

這只是錯誤的。你將一個國家隱藏到了它不應該的地方。如果某人在請求期間更改了'current_user',該怎麼辦?然後這兩個變量將不同步。 – theodorton 2012-02-26 02:44:34

0

這不是一個安全的方法:)保持你的狀態在控制器和模型中的業務邏輯。

如果需要將current_user傳遞給模型層,那麼模型不應該關心這是誰。您始終可以使用關聯來過濾對內容的訪問。

current_user.widgets.find(params[:id])

+0

我相信你錯了。這不是爲了實際存儲任何狀態;它實際上是爲了商業邏輯。這使我可以在更新時檢查模型內的所有權。例如在Post模型驗證中:self.user_id == User.current_user – tybro0103 2012-02-26 02:49:19

+0

這應該進入控制器。他們限制訪問,而不是模型本身。您可以通過重構控制器上的更新方法來使用has_many-association上的查找來完成此操作。 – theodorton 2012-02-26 02:51:12

+0

我知道這是一個宗教的事情,不管這是否被認爲是商業邏輯,但我相信它是。我可以在Post中創建一個方法,例如:def is_owner?(user)並在控制器中使用該方法,但在每個操作中都很乏味。 – tybro0103 2012-02-26 02:54:35