Rails 3上的所有者过滤的模型对象

我需要对我的ActiveRecord模型进行一些过滤,我想通过owner_id过滤我的所有模型对象。 我需要的东西基本上是ActiveRecord的default_scope。

但我需要通过会话变量进行过滤,该变量无法从模型中访问。 我已经阅读了一些解决方案 ,但没有一个可行,基本上任何一个都说你可以在声明default_scope时使用session。

这是我对范围的声明:

class MyModel  session[:user_id]) } ... end 

简单吧? 但它没有说方法会话不存在

希望你能帮忙

模型中的会话对象被认为是不好的做法,而应该根据current_user将一个类属性添加到User类中, around_filterApplicationController中的around_filter中设置。

 class User < ActiveRecord::Base #same as below, but not thread safe cattr_accessible :current_id #OR #this is thread safe def self.current_id=(id) Thread.current[:client_id] = id end def self.current_id Thread.current[:client_id] end end 

并在您的ApplicationController执行:

 class ApplicationController < ActionController::Base around_filter :scope_current_user def :scope_current_user User.current_id = current_user.id yield ensure #avoids issues when an exception is raised, to clear the current_id User.current_id = nil end end 

现在,在MyModel您可以执行以下操作:

 default_scope where( owner_id: User.current_id ) #notice you access the current_id as a class attribute 

您将无法将其合并到default_scope中。 由于没有会话,这将打破(例如)控制台内的每个用法。

你能做什么:添加一个方法像这样做你的ApplicationController

 class ApplicationController ... def my_models Model.where(:owner_id => session[:user_id]) end ... # Optional, for usage within your views: helper_method :my_models end 

无论如何,此方法将返回范围。

与会话相关的过滤是一项UI任务,因此它在控制器中占有一席之地。 (模型类无权访问请求周期,会话,cookie等)。

你想要的是什么

 # my_model_controller.rb before_filter :retrieve_owner_my_models, only => [:index] # action names which need this filtered retrieval def retrieve_owner_my_models @my_models ||= MyModel.where(:owner_id => session[:user_id]) end 

由于根据当前用户的所有权进行过滤是典型情况,您可以考虑使用标准解决方案,例如搜索’cancan gem,accessible_by’

还要注意default_scope的弊端。 rails3 default_scope,以及迁移中的默认列值