Cannot store object in session?


#1

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


#2

Wai T. 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!!!


#3

Phlip wrote:

Wai T. 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.


#4

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 T. 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!!!


#5

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


#6

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.