Model中默认范围内的参数

时间:2012-12-19 22:23:55

标签: ruby-on-rails-3 devise

我正在使用Devise来验证用户身份。我需要在所有表中基于global_location_id列显示/隐藏数据。当前global_location_id的值将来自current_user.global_location_id。我尝试将以下默认范围添加到我的某个模型中:

class Artifact < ActiveRecord::Base
default_scope where(:global_location_id => current_user.global_location_id)

但它会出现以下错误:

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

为了避免我在应用程序控制器中添加以下模型中的current_user不可用

class ApplicationController < ActionController::Base
   def set_global_location_id
    @global_location_id = current_user.global_location_id
   end

从我的控制器调用该方法

class ArtifactsController < ApplicationController
   #Check to see if the user is logged in first
   before_filter :authenticate_user!
   before_filter :set_global_location_id

更改模型中的默认范围以添加@global_location_id

class Artifact < ActiveRecord::Base
  default_scope where(:global_location_id => @global_location_id)

但这也不起作用。 @global_location_id正在应用程序控制器中正确设置。但它在模型中是空的。如何使它发挥作用。

1 个答案:

答案 0 :(得分:3)

不幸的是,您无法与模型实例共享在控制器中设置的实例变量(没有一些线程hackery)。这实际上是一件好事,因为否则它会像一个全局变量,这会给你带来更多弊大于利。

我实际上很难理解你为什么要这样做,因为它会在当前登录用户的状态和模型之间添加一些讨厌的耦合。如果您试图在控制台中找到Artifact,则current_user不存在,并且该实例变量将不可用,因此您将遇到一些严重问题。

这是你退后一步,问自己你真正想要做什么的点。您是否有任何理由需要根据当前用户的global_location_id隐式生成default_scope?您可以只创建一个常规范围并在控制器中使用它吗?

class Artifact < ActiveRecord::Base
  scope :by_global_location_id, lambda {|id| where(:global_location_id => id) }
end

class ArtifactsController < ApplicationController
  def index
    @artifacts = Artifact.by_global_location_id(current_user.global_location_id)
  end
end

这种方法的一个好处是,阅读代码的人不必花费大量时间来跟踪default_scope的工作方式。