Forum: Ruby on Rails Storing request-scoped data in a model

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Shak S. (Guest)
on 2009-04-09 19:40
Hi all,

What is the best way to store variables strictly for the lifetime of a
Rails' request?

I'm currently storing AR records in Rails.cache. Although this saves a
trip to the DB, I feel it's unnecessary to hit the cache more than once
per request (even when using MemoryStore there are Marshals involved).
Where is the best place to stash any stuff retrieved from the cache? It
doesn't need to (in fact, shouldn't) last past a single request.

An instance variable in ApplicationController sounds like it would do
this, but I would say such data should be kept with the model. Of course
a class variable in the model will keep its value each request (in
production) so is inappropriate for this.

Any ideas?

Shak
Andrew T. (Guest)
on 2009-04-10 10:19
(Received via mailing list)
On Thu, Apr 9, 2009 at 5:40 PM, Shak Shak
<removed_email_address@domain.invalid> wrote:
> doesn't need to (in fact, shouldn't) last past a single request.
>
> An instance variable in ApplicationController sounds like it would do
> this, but I would say such data should be kept with the model. Of course
> a class variable in the model will keep its value each request (in
> production) so is inappropriate for this.
>
> Any ideas?
>
> Shak
> --

It may be useful to understand a little more of what you're trying to
achieve.
If you're needing to keep something around for a request, an instance
variable in the controller may the right place because that manages
the the request.
Some more information on your specific problem will help us help you.

Andrew T.
http://ramblingsonrails.com
http://www.linkedin.com/in/andrewtimberlake

"I have never let my schooling interfere with my education" - Mark Twain
Shak S. (Guest)
on 2009-04-10 11:25
Andrew T. wrote:
> On Thu, Apr 9, 2009 at 5:40 PM, Shak Shak
> <removed_email_address@domain.invalid> wrote:
>> doesn't need to (in fact, shouldn't) last past a single request.
>>
>> An instance variable in ApplicationController sounds like it would do
>> this, but I would say such data should be kept with the model. Of course
>> a class variable in the model will keep its value each request (in
>> production) so is inappropriate for this.
>>
>> Any ideas?
>>
>> Shak
>> --
>
> It may be useful to understand a little more of what you're trying to
> achieve.
> If you're needing to keep something around for a request, an instance
> variable in the controller may the right place because that manages
> the the request.

My application often needs a list of application-specific "types". This
is a relatively static list of AR models. I also create sub lists based
on attributes of those types - so all the ones whose names which begin
with the letter "A", for instance. Each list is formed from a traversal
of the full list. These sub lists are accessible via the Class -
ApplicationTypes.get_all_a, for example.

To not repeat these traversals, I cache the computed lists. At the
moment, I'm using MemoryStore. Caching AR models there requires a
Marshal due to some odd (but known) behaviour
(https://rails.lighthouseapp.com/projects/8994-ruby...).
Taking stuff from the cache requires an unmarshall. Other cache stores
implicitly Marshal anyway.

So to save the repeated unmarshalling, I wanted a way to keep the
results of unmarshalling things from the cache on a per-request basis.
It's interesting to note that Rails 2.3 has this built in (for remote
caches, anyway). From the release notes:

"5.8 Improved Caching Performance

Rails now keeps a per-request local cache of read from the remote cache
stores, cutting down on unnecessary reads and leading to better site
performance. While this work was originally limited to MemCacheStore, it
is available to any remote store than implements the required methods."

I just want this kind of behaviour for a memorystore backed cache.

At the moment, I've just created a local hash of cached objects (created
on retrieval), which I clear using a public function called from an
before_filter in the ApplicationController. I guess this is the MVC way
of doing it too (maybe?). I do wonder how the mechanism in Rails 2.3
works though (since my way isn't really threadsafe), so any further
ideas would be welcome.

Shak
Andrew T. (Guest)
on 2009-04-13 10:10
(Received via mailing list)
On Fri, Apr 10, 2009 at 9:25 AM, Shak Shak
<removed_email_address@domain.invalid> wrote:
>>>
>
> (https://rails.lighthouseapp.com/projects/8994-ruby...).
> Rails now keeps a per-request local cache of read from the remote cache
> works though (since my way isn't really threadsafe), so any further
> ideas would be welcome.
>
> Shak
> --

Shak

If you're just keeping this information around for the request, I
don't know why you are storing it anywhere other than in the
controller as it is going to be re-calculated for every subsequent
request.
A simple example of this is authentication where a current user is
required throughout the request but will be a (potentially) different
user for each request processed by Rails.
This is a perfectly acceptable thing to store in the controller
implement like:

class ApplicationController < ...
  ...
  def current_user
    @current_user ||= get_current_user_somehow
  end
  ...
end

This way the user is 'figured out' once and then cached for each
subsequent call to current_user but finally discarded when the request
is complete.

Andrew T.
http://ramblingsonrails.com
http://www.linkedin.com/in/andrewtimberlake

"I have never let my schooling interfere with my education" - Mark Twain
This topic is locked and can not be replied to.