graphmeter
graphmeter

Reputation: 1125

Session variable not persisting after switch

I have tried to implement a switch between a basic and advanced viewing mode on a show page, essentially switching a basic/advanced div on/off through a link. In the controller I store the viewing-mode in a session variable (using a similar approach to http://railscasts.com/episodes/199-mobile-devices). Problem: the toggling works fine changing the viewing mode, but as soon as I click on a link to a different show-page in the non-default viewing-mode it takes me back to the default-mode, why is this?

show.html.erb

<% if viewing_mode? %>
    <%= link_to "Advanced", {mode: 0}  %>
<% else %>
    <%= link_to "Basic", {mode: 1} %>
<% end %>

<% if viewing_mode? %>
  <div class="container" id="basic">
   This is the basic view
  </div>

<% else %>
  <div class="container" id="advanced">
  This is the advanced view
  </div>
<% end %>

Controller

before_filter :prepare_for_viewing

def viewing_mode?
  if session[:viewing_param]
    session[:viewing_param] == "1"
  else
    session[:viewing_param] == "0"
  end
end
helper_method :viewing_mode?

def prepare_for_viewing
  session[:viewing_param] = params[:mode] if params[:mode]
end

Edit 1: Displaying the session parameters shows that the :viewing_params changes from:

"viewing_param"=>"1"

to

"viewing_param"=>"1.json"

after clicking on a link on a show page. This might be the problem, but why is the viewing_param modified in this way?

Edit 2: I got it to work after adding a hack, setting the "a.json" to "a", not a nice solution but it works:

def prepare_for_viewing
  session[:viewing_param] = params[:mode][0] if params[:mode]
end

Upvotes: 0

Views: 1578

Answers (3)

user1932315
user1932315

Reputation:

Had the same problem - session variables wasn't persisted, I've used session variable a lot so I think it's the key thing to recreate the bug

However I've overcome this issue by using cookies instead of session

Just simply instead of

session[:viewing_param] = ..
if session[:viewing_param]

use

cookies[:viewing_param] = ..
if cookies[:viewing_param]

There are advanced options available

 cookies[:key] = {
   :value => 'dummy value',
   :expires => 1.month.from_now,
   :domain => 'domainname.com'
 }

Here is how to delete it:

   cookies.delete(:key, :domain => 'domain.com')

After switching to cookies I wasn't able to spot any non-persisting issues.

Upvotes: 0

244an
244an

Reputation: 1589

This method seems to be incorrect? I made some comments

def viewing_mode?
  # this is true for all values except nil and false
  if session[:viewing_param]
    # should it be test here? Or setting a value?
    session[:viewing_param] == "1"
  else
    # can never be "0" here, because that value gives true in the test above
    session[:viewing_param] == "0"
  end
end

You are using this:

link_to "Advanced", {mode: 1}

for advanced link, and in this:

before_filter :prepare_for_viewing
def prepare_for_viewing
  session[:viewing_param] = params[:mode] if params[:mode]
end

You are setting session[:viewing_param] to "1" (when advanced), then in

def viewing_mode?
  if session[:viewing_param]
    session[:viewing_param] == "1"
  else
    session[:viewing_param] == "0"
  end
end

You are getting true, and that will give you "basic" view because of this:

<% if viewing_mode? %>
  <div class="container" id="basic">
   This is the basic view
  </div>

Upvotes: 1

AJcodez
AJcodez

Reputation: 34166

This is what I think you're trying to do (depending on which mode is the default):

before_filter :prepare_for_viewing
helper_method :advanced_view_mode?, :basic_view_mode?

def advanced_view_mode?
  session[:viewing_param] == '1'
end

def basic_view_mode?
  !advanced_view_mode?
end

def prepare_for_viewing
  session[:viewing_param] = params[:mode] if params[:mode]
end

Also try not to repeat markup, but if you have completely separate views, it might be worth it to render different pages all together.

<div class="container" id="<%= advanced_view_mode? ? 'advanced' : 'basic' %>">

  This is common content

  <%= render 'advanced/partial' if advanced_view_mode? %>
</div>

Upvotes: 1

Related Questions