Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Help debugging my session? Rails 3 ActionDispatch::Cookies::CookieOverflow

Even though I'm pretty sure I know why this error gets raised, I don't seem to know why or how my session is exceeding the 4KB limit...

My app was working fine, but once I deliberately started adding bugs to see if my transactions were rolling back I started getting this error.

To give some background, I'm busy coding a tournament application that (in this section) will create the tournament and then add some tournament legs based on the number of teams as well as populate the the tournament with some 'ghost fixtures' once the legs have been created.

The flash[:tournament] was working correctly before; using a tournament object, I have access to any AR validation errors as well as data that has been entered on the previous page to create the tournament.

TournamentController.rb

begin
  <other code>
  Tournament.transaction do
    tournament.save!
    Tournament.generate_legs tournament
    Tournament.generate_ghost_fixtures tournament
  end

  flash[:notice] = "Tournament created!"
  redirect_to :action => :index
rescue Exception => e
  flash[:tournament] = tournament
  redirect_to :action => :new, :notice => "There was an error!"
end

Tournament.rb

self.generate_ghost_fixtures(tournament)
  <other code>
  #Generate the ghost fixtures
  #tournament_legs is a has_many association
  tournament_legs_array = tournament.tournament_legs

  tournament_legs_array.each do |leg|
    number_of_fixtures = matches[leg.leg_code]

    #For the first round of a 32 team tournament, this block will run 16 times to create the matches
    number_of_fixtures.times do |n|
      Fixture.creatse!(:tournament_leg_id => leg.id, :match_code => "#{leg.leg_code}-#{n+1}")
    end
  end
end

I can do nothing but speculate as to why my session variable is exceeding 4KB?? Is it possible that the tournament object I pass through the flash variable contains all the associations as well?

Here is the dump of my session once I get the error.

Hope this is enough info to help me out :)

Thanks

Session Dump

_csrf_token: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
flash: {:tournament=>#<Tournament id: nil, tournament_name: "asd", tournament_description: "asdasd", game_id: 1, number_of_teams: 16, start_date: "2011-04-30 00:00:00", tournament_style: "single elimination", tournament_status: "Drafting", active: true, created_at: "2011-04-30 10:07:28", updated_at: "2011-04-30 10:07:28">}
player_id: 1
session_id: "4e5119cbaee3d5d09111f49cf47aa8fa"
like image 953
Gerrit Wessels Avatar asked Apr 30 '11 10:04

Gerrit Wessels


3 Answers

About dependencies, it is possible. Also save an ActiveRecord instance in the session is not a recommended aproach. You should save only the id. If you need it in all your requests use a before filter to retrieve it.

You can read more why is a bad idea at: http://asciicasts.com/episodes/13-dangers-of-model-in-session

like image 195
Pablo Castellazzi Avatar answered Oct 01 '22 11:10

Pablo Castellazzi


The generally accepted and recommended approach is to not use a redirect on error, but a direct render instead. The standard "controller formula" is this:

def create
  @tournament = Tournament.new(params[:tournament])
  if @tournament.save
    redirect ...
  else
    render 'new'  # which will have access to the errors on the @tournament object and any other instance variable you may define
  end
end

class Tournament < ActiveRecord::Base
  before_create :set_up_legs
end

On successful saving, you can drop all instance variables (thereby wiping the in-memory state) and redirect to another page. On failure (or exception) you keep the object in memory and render a view template instead (typically the 'new' or 'edit' form page). If you're using standard Rails validation and error handling, then the object will have an errors array that you can just display.

I'd also recommend you use ActiveRecord associations which automatically give you transactions. If you push all this into the model, e.g. a "set_up_legs" method or something, then you can use ActiveRecord error handling. This is part of the "skinny controller, fat model" paradigm.

like image 44
Wolfram Arnold Avatar answered Oct 01 '22 12:10

Wolfram Arnold


in session_store.rb, uncomment the last line with :active_record_store Now restart the server

like image 20
sanitha Avatar answered Oct 01 '22 12:10

sanitha