8

I am using this to access session in Model.

http://www.zorched.net/2007/05/29/making-session-data-available-to-models-in-ruby-on-rails/

Can anybody confirm that it will work with Apache + Passenger deployment too?

Or if there are any other alternatives to achieve the same?

Thanks,

Imran

kingsfoil
  • 3,795
  • 7
  • 32
  • 56
Saim
  • 2,471
  • 5
  • 30
  • 43

2 Answers2

25

I did not find any code on the internet that works, so I did some research and wrote my own. It works for Rails 3.2.x and probably on some other versions.

Insert this in your ApplicationController

  # Set a filter that is invoked on every request
  before_filter :_set_current_session

  protected
  def _set_current_session
    # Define an accessor. The session is always in the current controller
    # instance in @_request.session. So we need a way to access this in
    # our model
    accessor = instance_variable_get(:@_request)

    # This defines a method session in ActiveRecord::Base. If your model
    # inherits from another Base Class (when using MongoMapper or similar),
    # insert the class here.
    ActiveRecord::Base.send(:define_method, "session", proc {accessor.session})
  end

I will not remind you that accessing your session from a model may lead to bad code. Other posts may tell you, that you are stupid. Though there are some valid reasons to access the session from your model, like implementing a Model.save method, that saves to the current users session.

iblue
  • 29,609
  • 19
  • 89
  • 128
  • And how can I test it properly using Rspec? All my tests for the model I am using this now says `undefined local variable or method session'` – Lucas Nogueira Aug 17 '12 at 12:46
  • 7
    Your code is not thread-safe and will lead to issues in threaded environments (like `JRuby`, `Puma` server etc.) without `Rack::Lock`. Try `Thread.current[:session] = session` instead and access it through `Thread.current[:session]`. – Vikrant Chaudhary Jan 28 '15 at 06:16
  • 1
    @VikrantChaudhary works like a charm, this should be an answer. – max pleaner May 06 '16 at 17:58
2

Yes. It is the only efficient way I found to use session data in model. I also used it and never faced any deployment issue with Apache + passenger.

But you need to confirm when you will be playing with session values. On each new request to server, session value gets stored in thread and we can access it in model. If you are applying any logic by using thread value, then also make sure with situation when thread value might be nil also.

Because I got an issue where on development, my every code worked fine but on production, during starting server it caused an issue as initially it considered thread value as nil.

Nimesh Nikum
  • 1,809
  • 13
  • 17
  • Thanks Nimsesh. Here is the scenario where I do need to access the session in Model: 1. In ActiveRecord Observer to update a field -- with a value from session -- for every record. 2. setting a field of current_user (restful_authentication). Will the every user hold the different value which is being set on login? – Saim Nov 25 '10 at 19:45
  • Yes. Just look at again here http://www.zorched.net/2007/05/29/making-session-data-available-to-models-in-ruby-on-rails/... It has `before_filter :set_user` which saves the session value on each new request to thread. That means every user hold different value because everyone's request is different and such a way thread keeps on updating with different values – Nimesh Nikum Nov 25 '10 at 20:05