模型中默认范围的参数 [英] Parameter in default scope in Model
问题描述
class Artifact< ActiveRecord :: Base
default_scope其中(:global_location_id => current_user.global_location_id)
但是它给出以下错误:
未定义的局部变量或方法`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
#检查用户是否先登录
before_filter:authenticate_user!
before_filter:set_global_location_id
将模型中的默认范围更改为添加@global_location_id
class Artifact< ActiveRecord :: Base
default_scope其中(:global_location_id => @global_location_id)
但是也不行。在应用程序控制器中正确设置了@global_location_id。但在模型中它是空的。
不幸的是,您将无法共享在控制器中设置的实例变量与模型的实例(没有一些线程黑客)。这实际上是一件好事,因为否则它会像一个全局变量,这会导致你的伤害更大。
我其实很难了解为什么你想这样做,因为它会增加当前登录用户的状态与模型之间的一些讨厌的耦合。如果您尝试在控制台中找到工件,则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的工作原理。
I am using Devise to authenticate users. I need to show/hide data based on global_location_id column in all my tables. The value of current global_location_id will come from current_user.global_location_id. I tried adding a following default scope to one of my models:
class Artifact < ActiveRecord::Base
default_scope where(:global_location_id => current_user.global_location_id)
But it gives following error:
undefined local variable or method `current_user' for #<Class:0x8721840>
To circumvent the unavailability of current_user in models I added following to my application controller
class ApplicationController < ActionController::Base
def set_global_location_id
@global_location_id = current_user.global_location_id
end
And called the method from my controller
class ArtifactsController < ApplicationController
#Check to see if the user is logged in first
before_filter :authenticate_user!
before_filter :set_global_location_id
Changed the default scope in model to add @global_location_id
class Artifact < ActiveRecord::Base
default_scope where(:global_location_id => @global_location_id)
But this does not work either. The @global_location_id is being set properly in application controller. But it is empty in the model. How to make it work.
Unfortunately you aren't going to be able to share an instance variable that's set in the controller with an instance of the model (without some thread hackery). This is actually a good thing though because otherwise it would be acting like a global variable, which would cause you more harm than good.
I'm actually having a hard time understanding why you would want to do it this way because it would add some nasty coupling between the state of the currently logged in user and your model. If you tried to find an Artifact in the console, the current_user does not exist, and that instance variable would not be available, so you would have some serious problems.
This is the point where you step back and ask yourself what you're really trying to do. Is there any reason why you need to make the default_scope implicitly based on the current user's global_location_id? Could you just just create a regular scope and use that in your controller instead?
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
One benefit of this approach is that someone reading your code doesn't have to spend a ton of time tracking down how the default_scope is working.
这篇关于模型中默认范围的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!