Rails 3的devise,current_user不能在模型中访问?

在我的project.rb模型中,我试图创build一个dynamicvariables的作用域:

scope :instanceprojects, lambda { where("projects.instance_id = ?", current_user.instance_id) } 

我得到以下错误:

 undefined local variable or method `current_user' for #<Class:0x102fe3af0> 

在控制器中,我可以访问current_user.instance_id …有没有原因模型无法访问它,并获得访问的方式? 此外,这是创build一个像上面的范围,还是属于控制器的正确的地方?

正如你已经指出的那样,这没有什么意义。 current_user根本不属于模型逻辑,应该在控制器级别上进行处理。

但是您仍然可以创build这样的范围,只需从控制器传递参数即可:

 scope :instanceprojects, lambda { |user| where("projects.instance_id = ?", user.instance_id) } 

现在你可以在控制器中调用它:

 Model.instanceprojects(current_user) 

已经接受的答案提供了一个非常正确的方法来实现这一点。

但是这里是User.current_user技巧的线程安全版本。

 class User class << self def current_user=(user) Thread.current[:current_user] = user end def current_user Thread.current[:current_user] end end end class ApplicationController before_filter :set_current_user def set_current_user User.current_user = current_user end end 

这个按预期工作,但是可以被认为是肮脏的,因为我们在这里基本上定义了一个全局variables。

瑞安·贝茨(Ryan Bates) 在这个railscast中提出了一个非常安全的方法来实现这种策略

这是一个付费插曲(不投票给我!),但你可以免费浏览源代码

在这里他创build了一个current_tenant方法,但是您可以轻松replacecurrent_user

这里是代码的关键位…

 #application_controller.rb around_filter :scope_current_tenant private def current_tenant Tenant.find_by_subdomain! request.subdomain end helper_method :current_tenant def scope_current_tenant Tenant.current_id = current_tenant.id yield ensure Tenant.current_id = nil end #models/tenant.rb def self.current_id=(id) Thread.current[:tenant_id] = id end def self.current_id Thread.current[:tenant_id] end 

那么在模型中,你可以做一些像…

 default_scope { where(tenant_id: Tenant.current_id) } 

你不需要使用范围。 如果你已经在模型中设置了适当的关联,那么在控制器中放置一段代码就可以做到这一点:

 @projects = current_user.instance.projects