模型中默认范围的参数 [英] Parameter in default scope in Model

查看:113
本文介绍了模型中默认范围的参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆