Storing Objects in a Session in Rails
The main reason not to store objects in the session is that if the object structure changes, you will get an exception. Consider the following:
class Foo
attr_accessor :bar
end
class Bar
end
foo = Foo.new
foo.bar = Bar.new
put_in_session(foo)
Then, in a subsequent release of the project, you change Bar's name. You reboot the server, and try to grab foo out of the session. When it tries to deserialize, it fails to find Bar and explodes.
It might seem like it would be easy to avoid this pitfall, but in practice, I've seen it bite a number of people. This is just because serializing an object can sometimes take more along with it than is immediately apparent (this sort of thing is supposed to be transparent) and unless you have rigorous rules about this, things will tend to get flummoxed up.
The reason it's normally frowned upon is that it's extremely common for this to bite people in ActiveRecord, since it's quite common for the structure of your app to shift over time, and sessions can be deserialized a week or longer after they were originally created.
If you understand all that and are willing to put in the energy to be sure that your model does not change and is not serializing anything extra, you're probably fine. But be careful :)
Rails session store model object
Always use cart object. initialize it from session, do operations and in the end serialize it back to session.
class Cart
def initialize(params={})
@items = params[:items] || []
end
end
controller:
@cart = Cart.new(session[:cart])
//do operations on cart
session[:cart] = @cart
How to store ActiveRecord object in session using Rails?
Storing objects in the session is a bad idea.
Storing Objects in a Session in Rails
Better to store the id
of the object so you can always check if the object in on the latest state.
Storing and retrieving session objects
In Ruby, hash keys work by equality. You can store and retrieve a value in a hash as long as the key you're using is equal to the key that's stored.
For instance:
hsh = { 'hello' => 'world' }
p hsh['hello'] #=> "world"
'hello'.eql? 'hello' #=> true
You can retrieve the value because the same value string is always eql?
in Ruby.
This is not the case for most objects:
class Example; end
object1 = Example.new
object2 = Example.new
object1.eql? object2 #=> false
Therefore, the key that you use to store in the hash must be eql?
to the one that you're using to retrieve. eql?
is equivalent to ==
and equal?
.
You're creating two instances of ImportantData
, which will not be equal to each other. It looks like you can accomplish what you want with a single hash key:
hash_value = ImportantData.new
hash_value.test_id = params[:test_id]
hash_value.user_id = params[:user_id]
session[:important_data] ||= hash_value
puts session[:important_data].class.name #=> ImportantData
session[:important_data].test_id #=> puts out value of test_id
Why is my ruby object being converted to a Hash after saving it in a session and how do I retain it's status as an object?
You're not meant to stuff random objects into a Rails session. Sessions are essentially a key-value store of strings, so what you're seeing is automatic flattening of objects into a form that the session can manage.
You're better off converting your object to JSON before passing it to the session and decoding it after retrieving it. In your situation, you could also just create a constructor that takes all necessary fields of your Board object as parameters and reconstruct the Board within the receiver method or use Ruby's Marshal module to get what you want.
You can also store your Board in something more persistent (cache or even database) and just pass an ID to your session. The receiver can then retrieve the row based on ID and reconstruct the object.
How OpenStruct stored in session
A session usually consists of a hash of values and a session id,
usually a 32-character string, to identify the hash. Every cookie sent
to the client's browser includes the session id. And the other way
round: the browser will send it to the server on every request from
the client.
You should either serialize your objects before storing them in the session.
session[:info] = OpenStruct.new(first_field: 1, second_field: 'two').to_yaml
and retrieve it using
YAML.load(session[:info])
from the rails documentation
Do not store large objects in a session. Instead you should store them
in the database and save their id in the session. This will eliminate
synchronization headaches and it won't fill up your session storage
space (depending on what session storage you chose, see below). This
will also be a good idea, if you modify the structure of an object and
old versions of it are still in some user's cookies. With server-side
session storages you can clear out the sessions, but with client-side
storages, this is hard to mitigate.
or change your session store from cookie_store
to cache_store
In your environment
change
config.session_store :cookie_store
to
config.session_store :cache_store
Related Topics
How to Wrap Link_To Around Some HTML Ruby Code
Find Key/Value Pairs Deep Inside a Hash Containing an Arbitrary Number of Nested Hashes and Arrays
Heroku Not Sending Email With Gmail Smtp
What Does Class_Eval ≪≪-"End_Eval", _File_, _Line_ Mean in Ruby
Rails 4.0 Strong Parameters Nested Attributes With a Key That Points to a Hash
How to Install Rvm on Windows 7
Getting "Warning! Path Is Not Properly Set Up" When Doing Rvm Use 2.0.0 --Default
Error: Mime-Types-Data Requires Ruby Version >= 2.0
In Ruby on Rails, Are '#Encoding: Utf-8' and 'Config.Encoding = "Utf-8"' Different
Exporting an Environment Variable in Ruby
Converting String from Snake_Case to Camelcase in Ruby
Ruby 1.9.2 How to Install Rmagick on Windows
What Are the Magic $-Prefixed Variables in Ruby