最佳做法是讓你的模型是無狀態的,控制器獲取處理狀態。如果你想讓這些信息到達你的模型,你需要從控制器傳遞它。在這裏使用創建鉤子並不是真正正確的方法,因爲您正在嘗試添加有狀態數據,而這些鉤子確實適用於無狀態行爲。
您可以從控制器傳遞信息中:
Foo.new(params[:foo].merge {:creator_id => current_user.id})
或者,您可以創建方法上的用戶來處理這些操作:如果您發現自己寫了很多的權限代碼
class User
def create_foo(params)
Foo.new(params.merge! {:creator_id => self.id})
end
end
在控制器中,我會使用選項2,因爲它會讓您將該代碼重構爲模型。否則選項1更清潔。
奧馬爾指出,它自動化很棘手,但它仍然可以完成。這裏有一種方法,使用create_something實例方法用戶:
def method_missing(method_sym, *arguments, &block)
meth = method_sym.to_s
if meth[0..6] == "create_"
obj = meth[7..-1].classify.constantize.new(*arguments)
obj.creator_id = self.id
else
super
end
end
你也可以重寫構造要求建設user_ids,或者裏面創建的ApplicationController的方法,它包裝新。
有可能是一種更優雅的方式來做事情,但我絕對不喜歡嘗試從模型代碼中讀取狀態,它打破了MVC封裝。我更喜歡以某種方式明確地傳遞它。
它避免了執行Thread.current,但使用全局變量和中央模塊來跟蹤當前用戶。 – 2009-07-06 11:47:21
它現在使用Thread.current。 – 2010-11-04 08:25:37