Search code examples
ruby-on-railsruby-on-rails-3sessiondefault-scope

Owner-filtered model objects on Rails 3


I need to do some filtering on my ActiveRecord models, I want to filter all my model objects by owner_id. The thing I need is basically the default_scope for ActiveRecord.

But I need to filter by a session variable, which is not accessible from the model. I've read some solutions, but none works, basically any of them says that you can use session when declaring default_scope.

This is my declaration for the scope:

class MyModel < ActiveRecord::Base
    default_scope { where(:owner_id => session[:user_id]) }
    ...
end

Simple, right?. But it fails saying that method session does not exists.

Hope you can help


Solution

  • Session objects in the Model are considered bad practice, instead you should add a class attribute to the User class, which you set in an around_filter in your ApplicationController, based on the current_user

    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
    

    and in your ApplicationController do:

    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
    

    And now in your MyModel you can do the following:

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