开发者

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 t开发者_如何学Pythonimes 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"


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


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.


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


I would convert the exception to string before assigning it to flash[:tournament] with 'to_s'. I had the same error and it seems assigning an exception object to a session variabla like flash means it takes the whole stack trace with it into the session. Try it, worked for me.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜