我正在使用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正在应用程序控制器中正确设置。但它在模型中是空的。如何使它发挥作用。
答案 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的工作方式。