Session in Rails vs Session in rhodes - rhomobile

In Rails its easy to store and retrieve session variables.
for e.g
session[:user_id] = #current_user.id
I was wondering if there is something this like in rhodes too.
Like in rails request parameters are accessible through
params['name']
while in rhodes its
#params['name']
If there is nothing like session variable, can anyone suggest some work around for managing sessions. like using global variables that are available across multiple requests.
Comments/Hints, please?
thanx.

I implemented my own session in rhodes.
Assuming that a rhodes app will have only one user you don't need to detect in wich user or "session" you are, so you will have only one session.
I created a global hash, named $session, where you put and get your values:
In the application.rb I put this:
$session ||= {}
And I use it thus:
$session[:user] = 'john'
puts $session[:user]

You could also store persistent values in the Redis database as a key/value pairs database.

Related

Updating and accessing a session with Ruby on Rails

I'm working with ruby on rails 2.5.
I have an object "payment_plan". This object can change with a toggle behavior that changes, and I need to keep this object alive thorough all the session and at the end it should be save par of it in my mongo db. I need to access the latest status of the object always. The controller should be capable to update the object and the view should be able to access the latest state of the object.
Any insights on how to do something like this would be great :)
I have try to create a helper function in the application controller but had problem accessing it from the view.
Also I prefer not to save the state of the object in the db, because it will be too many db calls later.
To access a controller helper function from view, define it as a helper:
class SomeController < ApplicationController
helper def some_helper
end
end
As for storing some data in session - it's ok, rails has nice session store mechanism for session[:my_object_prop] = 1/session[:my_object_prop] (see in official guide)
But keep in mind, that:
by default session is stored in cookies, which are passed in headers from client browser with every request to your server (even to images, if they are on the same domain), so it's only practical to save small amounts of data there.
user can clear their's cookies and data will be lost (this is usually fine)
the opposite of the latter - a user may come to your app with session data from old version of your code
thank you very much, that was very helpfull!
Another question, can I override a session value after setting it up?
for example session[:plan_id]="plan_id_1" and they further on in the run do something like this: session[:plan_id]="plan_id_2"
thanks!!!

Alter heroku's config var in my rails app

I intent to change it when the admin user log in and log out. Is it possible and how can I do it?
You can change environment variables through the ENV hash.
For example, you can have a method like this which gets called when the logout button is clicked:
def logout_admin
ENV["ADMIN_LOGGED_IN"] = false
end
This isn't a typical way to do auth. Usually people use a session token in the database. Really you can use the ENV the hash the same as global variables (it won't persist if you reboot the rails app, anyway).

Migrating sessions from cookie_store to Redis in Rails 3

I need to switch the session store in my Rails 3 app from cookie_store to redis-session-store. There are many reasons for this (security, SSO with other Rails and non-Rails apps). Are there any best practices on how to do it without loosing all current sessions?
What i could imagine is a two steps approach:
Collect all user sessions for N days and store them in the DB or in Redis (update if already stored).
Use stored user sessions to create entries in Redis.
Alternatively, on the fly migration would also be possible. Means read cookies, use secret key to decrypt the session data and store it as a new session in Redis.
I realize this ticket is pretty old, but this may help others. We ended up changing our session store to Redis, but then still looking for the legacy cookie (for a week or two) before no longer respecting them.
There are probably some security concerns to consider before using this strategy - you want to make sure those risks are worth it compared to the cost of having to sign your entire user-base out all at once. With Rails, the cookies are encrypted and can't be tampered with.
Here's what we used:
class SessionsController < Devise::SessionsController
LEGACY_COOKIE_NAME = "_old_session_name".freeze
def new
return if detect_valid_cookie
super
end
private
def detect_valid_legacy_cookie
legacy_cookie = request.cookie_jar.encrypted[LEGACY_COOKIE_NAME].presence || {}
valid_user_id = legacy_cookie['warden.user.user.key'].try(:first).try(:first)
return unless valid_user_id
user = User.find_by(:id => valid_user_id)
return unless user
if sign_in user
request.cookie_jar.delete(LEGACY_COOKIE_NAME)
redirect_to root_path # or whever you want
true
else
false
end
end
end
Stolen from here:
http://www.happybearsoftware.com/almost-protect-yourself-from-cookie-session-store.html (the last two sections)
Basically, use this:
Rails.application.config.action_dispatch.cookies_serializer = :hybrid
Quote follows:
This will cause Rails to accept sessions serialized with Marshal and exchange them for sessions serialized with JSON.
After you're confident that all your users sessions have been converted to JSON, you can roll out another release that flips the config value to :json.
Note: If you're storing complex Ruby objects in the session and need them to be serialized with Marshal, you won't be able to use the JSON serializer.

How do I store an instance variable across multiple actions in a controller?

Say I want to store some variable in my controller. I want to initialize it in one action, increment it in another, and read it in yet another. Just declaring this variable with #foo doesn't work because #foo dies after the action that created it is rendered.
I do not want this variable to be stored in a model.
Is there a way to preserve this variable besides storing it in a session?
It seems like I've run into this simple problem a few times, and I want to know the best way to go about solving it.
Not really. Each call to a controller action is stateless. Nothing is available after the controller action finishes. A new controller instance is created for each request, and then discarded at the end of the request.
If you don't want to store it in the session, or database model, you don't have many options if you're wanting that variable to be specific to a particular session.
If it is global across all sessions, you could put it in a ##class_variable rather than an #instance_variable, but that can get messy once you start having multiple Rails processes (each which will have their own copy of it), or if you're running in threadsafe mode, you can end up with nasty concurrency bugs.
I guess you could look at something like memcached, but you'd still need to key that to some user_id or other session marker (unless it's global)
I too am wondering why you are against using session? If you don't like working with session directly in your actions, you could emulate a surviving #foo instance variable with filters. Something like this maybe?
class FooController < ApplicationController
before_filter :load_foo
after_filter :save_foo
private
def load_foo
#foo = session[:foo] || 0
end
def save_foo
session[:foo] = #foo
end
end
Your actions will the be able to manipulate the value through the #count instance variable and this will be automatically persisted to session.
You could make use of the built in Rails.cache mechanism to store the value but as mentioned in the first answer you'd have to key it off something like the user_id. This is a nice way to go since you can back it with different storage mechanisms.
Rails.cache.write(:foo)
# in later action
Rails.cache.read(:foo)
One other thing you could look at is the flash hash, which provides a keep method to make the flash value last more than one subsequent request.
So in action 1 you could create the value:
flash[:foo] = some_value
flash.keep(:foo)
In action 2 you can access it, and call keep again if you want it to stay alive for more subsequent actions.
flash[:foo] #use it for something
flash.keep(:foo) # keep it for another request
It's a bit of a tricky thing to do cleanly within the context of http requests.
If it's a simple count or string, I think the best solution is to store it in the session. That way it will be there if you are using multiple web servers.
Why are you against using a session for this?
Don't worry, sessions won't bite.
Also, the session is probably the best way to do this.

Retrieve session with session_id in Ruby On Rails?

I want to access the session of a user from a different domain than the one that I initiated the session. Can I use session.session_id of the user and then retrieve the session hash of that user ?
Thank you
If it's on a different domain (i.e., not a subdomain), there's no way to get the session info (cause it's stored in a cookie)—you'll need something else (see this question). If it's a subdomain, I think there's a neat way to do it automatically by setting the cookie's domain (look in environment.rb's config.action_controller.session, try setting :session_domain)
It looks like you could use something like:
CGI::Session::ActiveRecordStore::SqlBypass::find_by_session_id(session_id)
However, I'm not sure if that's a good idea or not -- and in this case it is only useful if you're using the ActiveRecordStore. Not sure what else is available on the other stores, but if you poke around under actionpack/lib/action_controller/session/* you'll probably get a more definitive answer.

Resources