Unable to change Sessions in Sinatra App - ruby

I am currently working with a Sinatra app, and struggling to re-set my session variable. This is not your typical "my session disappeared" issue - the problem is I can't alter or change the sessions I have set. Maybe this is a dumb question, and they aren't supposed to change, but that seems like less of a value to my project, as I need to set and then later change a session variable. General code concept below -
get '/' do
session[:data] = {:key, 'default'}
p session[:data] #{"key","default"}
end
post '/:data' do
p params[:data] #"data"
session[:data] = {:key, params[:data]}
end
get '/anotherpage' do
p session[:data] #{"key","default"} as result, even after posting to /:data
end
The session[:data] persists across various routes no problem, but I cannot update, remove, change, anything. Any ideas?

Related

Rails: Flash messages doesn't clear until it is read/accessed

I set the flash message as below in one of my routes
def signup
flash[:is_signup] = true
... redirect_to route1 : route2 // based on some logic, redirect accordingly
end
def route1
// access flash[:is_signup]
flash.discard(:is_signup)
// do something
end
As depicted above, after i set the flash variable, i could redirect_to either the route(route1) that uses this flash variable or another route(route2) that doesn't care about this flash variable at all.
The issue is, when i redirect to route2, and then go on and mind my own business, hitting several routes/actions in the process, when i end up hitting the route1, the flash variable is still there.
I haven't seen anything in the documentation that says it is available until it is read. Is this the case? or am i doing something wrong?
Thanks in Advance
I'm seeing this as well (rails 4.2.11), and agree: no docs indicate access of flash should be necessary.
But, if I have a page that sets flash[:blah] = 'applesauce' and consumes the flash (e.g., puts flash[:blah]) on the next request, that key is not present in the following request. If I don't, it will linger through request after request until I hit a one where I check the flash.
My workaround is this:
In application_controller.rb
class ApplicationController < ActionController::Base
before_action :touch_flash
#...
def touch_flash
flash
end
end
This act of referencing flash appears to be enough to trigger a discard at end of the request (but doesn't interfere with any actual access later in the request). Next request, it's gone as expected.

rails persist objects over requests in development mode

I am trying to interact with Matlab.Application.Single win32ole objects in my rails application. The problem I am running into is that while I am developing my application, each separate request reloads my win32ole objects so I loose the connection to my matlab orignal instances and new instances are made. Is there a way to persist live objects between requests in rails? or is there a way to reconnect to my Matlab.Application.Single instances?
In production mode I use module variables to store my connection between requests, but in development mode Module variables are reloaded every request.
here is a snippet of my code
require 'win32ole'
module Calculator
#engine2 = nil
#engine3 = nil
def self.engine2
if #engine2.nil?
#engine2 = WIN32OLE.new("Matlab.Application.Single")
#engine2.execute("run('setup_path.m')")
end
#engine2
end
def self.engine3
if #engine3.nil?
#engine3 = WIN32OLE.new("Matlab.Application.Single")
#engine3.execute("run('setup_path.m')")
end
#engine3
end
def self.load_CT_image(file)
Calculator.engine2.execute("spm_image('Init','#{file}')")
end
def self.load_MR_image(file)
Calculator.engine3.execute("spm_image('Init','#{file}')")
end
end
I am then able to use my code in my controllers like this:
Calculator.load_CT_image('Post_Incident_CT.hdr')
Calculator.load_MR_image('Post_Incident_MRI.hdr')
You can keep an app-wide object in a constant that won't be reset for every request. Add this to a new file in config/initializers/:
ENGINE_2 = WIN32OLE.new("Matlab.Application.Single")
You might also need to include the .execute("run('setup_path.m')") line here as well (I'm not familiar with WIN32OLE). You can then assign that object to your instance variables in your Calculator module (just replace the WIN32OLE.new("Matlab.Application.Single") call with ENGINE_2, or simply refer to them directly.
I know this is beyond the scope of your question, but you have a lot of duplicated code here, and you might want to think about creating a class or module to manage your Matlab instances -- spinning up new ones as needed, and shutting down old ones that are no longer in use.

Sinatra sessions - why is what I put in different from what I get out?

I've got the following declared:
set :sessions, true
and then in my controller, I have:
session[$session_id] = user.session_id if save_successful
which sets the session, and then on a trip back to the server, I have:
session_id = session[$session_id]
But when I compare what I initially store in the session, I have:
a878bbd83f217daabec1b160b00bdde6 (initally)
d1e6264b87ae240be5a25a7edbcc97e5688df133cada1c7ab50661ae2f752b48 (on trip back)
Why is what I put into a session different from what I get out? and how do I make it the same???
Cheers,
Louis
I assume you meant for $session_id to be :session_id or 'session_id', variables that begin with dollar signs are global in Ruby (it is not the name of a key, but instead a globally visible reference to some object).
A good way to take a look would be to print session.inspect is the key what you think it should be?
I've posted a bug report on https://github.com/rack/rack/issues/197#issuecomment-1648851
If I use just :id instead of :session_id then it works :~)

rails session_store odd behaviour

I am using active_record_store in a rails application which is storing this in session session[:email] = "email#address.com"
now this works fine in the action. but when this action gets over and is redirected to another page, which also accesses the same session[:email] I get an error
undefined method `eq' for nil:NilClass
this should probably mean that i am trying to compare values at some place i am not allowed to. but i cannot see anything like that in the code.
This looks like an old question, but I was just having the same problem and had to figure it out on my own, and thought I would post the solution up here for anyone else that runs into this. It's not very well documented, but to get this to work you have to add:
config.action_dispatch.session_store = :active_record_store
to application.rb, and
Application.config.session_store :active_record_store
to config/initializers/session_store.rb. Then, you have to do:
rake db:sessions:create
and:
rake db:migrate
Then, you have to restart your rails server. I think it was the db:sessions:create step that tripped up the original poster. Not only does that database table have to be laid out the way rails is expecting (that is, with an 'id' column, which is the actual cause of this error, I think), but also the current session has to have a valid ID. Hence the need to create the table and re-start the server, or potentially empty the table if it exists.

Get absolute (base) url in sinatra

Right now, I do a
get '/' do
set :base_url, "#{request.env['rack.url_scheme']}://#{request.env['HTTP_HOST']}"
# ...
haml :index
end
to be able to use options.base_url in the HAML index.haml.
But I am sure there is a far better, DRY, way of doing this. Yet I cannot see, nor find it. (I am new to Sinatra :))
Somehow, outside of get, I don't have request.env available, or so it seems. So putting it in an include did not work.
How do you get your base url?
You can get it using request.base_url too =D (take a look at rack/request.rb)
A couple things.
set is a class level method, which means you are modifying the whole app's state with each request
The above is a problem because potentially, the base url could be different on different requests eg http://foo.com and https://foo.com or if you have multiple domains pointed at the same app server using DNS
A better tactic might be to define a helper
helpers do
def base_url
#base_url ||= "#{request.env['rack.url_scheme']}://#{request.env['HTTP_HOST']}"
end
end
If you need the base url outside of responding to queries(not in a get/post/put/delete block or a view), it would be better to set it manually somewhere.

Resources