Forum: Ruby on Rails Cannot store object in session?

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.
7c8f8b6eae4dd991e3a9065c68451361?d=identicon&s=25 Wai Tsang (sneptune)
on 2007-02-04 16:21
I am trying to store status information, but whenever I tried to call
the methods inside the session object, it would complain about this:

NoMethodError in TestController#getstatus

You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occured while evaluating nil.include?

Here's the code I use:

class TestController < ApplicationController
  def index

  end

  def getlog
      session[:s1] ||= Status.new
      render :text => session[:s1].gettext
  end

end

class Status < ActiveRecord::Base
  @@ccount = 0

  def self.gettext
    @@ccount += 1
  end
end
Aafa8848c4b764f080b1b31a51eab73d?d=identicon&s=25 Phlip (Guest)
on 2007-02-04 16:44
(Received via mailing list)
Wai Tsang wrote:

> I am trying to store status information, but whenever I tried to call
> the methods inside the session object, it would complain about this:
>
> NoMethodError in TestController#getstatus

Your session store in files like tmp/sessions/ruby_sess.ff73c12d9549c9de
.

Open one as text and read it. It shows "serialized" objects, meaning
object
that are converted into strings for cold storage.

Ruby objects are supposed to live in memory; think of them as 2D
entities.
Strings can only contain 1D entities. Some objects can't handle the
flattening process; it squeezes the life out of them.

By and large, don't use the session object unless you must. And between
two
events (two controller actions, for example), never assume that the Ruby
process running Rails is the same instance. The session hash cannot
store a
reference to an object in memory (like a real Hash would), it can only
store
a serialized copy of the object.

All communication between two events should be as thin and simple as
possible. Store your object in a Model with an id, and pass this id
between
events somehow. I prefer to pass it as hidden fields in the View, but
you
can go ahead and use the session hash for that.

--
  Phlip
  http://www.greencheese.us/ZeekLand <-- NOT a blog!!!
7c8f8b6eae4dd991e3a9065c68451361?d=identicon&s=25 Wai Tsang (sneptune)
on 2007-02-04 16:56
Phlip wrote:
> Wai Tsang wrote:
>
>> I am trying to store status information, but whenever I tried to call
>> the methods inside the session object, it would complain about this:
>>
>> NoMethodError in TestController#getstatus
>
> Your session store in files like tmp/sessions/ruby_sess.ff73c12d9549c9de
> .
>
> Open one as text and read it. It shows "serialized" objects, meaning
> object
> that are converted into strings for cold storage.
>
> Ruby objects are supposed to live in memory; think of them as 2D
> entities.
> Strings can only contain 1D entities. Some objects can't handle the
> flattening process; it squeezes the life out of them.
>
> By and large, don't use the session object unless you must. And between
> two
> events (two controller actions, for example), never assume that the Ruby
> process running Rails is the same instance. The session hash cannot
> store a
> reference to an object in memory (like a real Hash would), it can only
> store
> a serialized copy of the object.
>
> All communication between two events should be as thin and simple as
> possible. Store your object in a Model with an id, and pass this id
> between
> events somehow. I prefer to pass it as hidden fields in the View, but
> you
> can go ahead and use the session hash for that.
>
> --
>   Phlip
>   http://www.greencheese.us/ZeekLand <-- NOT a blog!!!

Thanks for the quick reply.  I tried storing the information in the
model, but the information in the model cannot be retained.  For
example, if I stored an global class variable @@ccount in Status, and
Status.gettext would increase the @ccount, when I output the value of
gettext in Status, it is always 1.  It seems like the model is created
from scratch everytime the controller tried to call the methods inside.
Ab04ca6bc3b1f92322b8094151afe92e?d=identicon&s=25 Vicent.Z (Guest)
on 2007-02-04 17:16
(Received via mailing list)
i think you should use the global var,start with "$"
the class-var is not persisstence between user-actions.
Aafa8848c4b764f080b1b31a51eab73d?d=identicon&s=25 Phlip (Guest)
on 2007-02-04 17:33
(Received via mailing list)
Vicent.Z wrote:

> i think you should use the global var,start with "$"
> the class-var is not persisstence between user-actions.

Never do that, because (among many other reasons) you should never
assume
that the Ruby instance that serves one Action is the same as serves the
next
one. Your server could reboot, for example, between each time the user
looks
at a View.

Wai Tsang wrote:

> Thanks for the quick reply.  I tried storing the information in the
> model, but the information in the model cannot be retained.  For
> example, if I stored an global class variable @@ccount in Status, and
> Status.gettext would increase the @ccount, when I output the value of
> gettext in Status, it is always 1.  It seems like the model is created
> from scratch everytime the controller tried to call the methods inside.

What is ccount? The first step here is to give it a complete,
self-documenting name. Programs are hard enough to read without abusing
private acronyms.

Do you really need a variable to count something, for the lifespan of
the
Rails website, such that each user sees a new value in it? If so, I
would
store it in a YAML file, and open it at a path like RAILS_ROOT +
'/lib/my.yaml'. Then YAML::load it when you need it and YAML::dump it
when
it changes.

If you don't want to do that, note the only members of a Model that
store in
a database are the attribute ones - not any extra variable you make, and
certainly not the class-instance @@ variables.

Make another Model and put only one record in it, with ccount in that
(with
a better name). Then find(:first) this Model instance when you need the
record, and save it when it changes.

--
  Phlip
  http://www.greencheese.us/ZeekLand <-- NOT a blog!!!
7c8f8b6eae4dd991e3a9065c68451361?d=identicon&s=25 Wai Tsang (sneptune)
on 2007-02-05 15:28
Phlip wrote:

> Do you really need a variable to count something, for the lifespan of
> the
> Rails website, such that each user sees a new value in it? If so, I
> would
> store it in a YAML file, and open it at a path like RAILS_ROOT +
> '/lib/my.yaml'. Then YAML::load it when you need it and YAML::dump it
> when
> it changes.
>
> If you don't want to do that, note the only members of a Model that
> store in
> a database are the attribute ones - not any extra variable you make, and
> certainly not the class-instance @@ variables.
>
> Make another Model and put only one record in it, with ccount in that
> (with
> a better name). Then find(:first) this Model instance when you need the
> record, and save it when it changes.
>
> --
>   Phlip
>   http://www.greencheese.us/ZeekLand <-- NOT a blog!!!

It is just a sample code, but yeah, I would need to store some
information about the session, such as whether an action has been
completed and how many times it has been ran.  I will look into YAML,
thanks a lot.
This topic is locked and can not be replied to.