module Merb module SessionMixin def setup_session MERB_LOGGER.info("Setting up session") @session = Merb::Session.persist(cookies) @fingerprint_before = Marshal.dump(@session).hash end def finalize_session MERB_LOGGER.info("Finalize session") unless Marshal.dump(@session).hash == @fingerprint_before @session.save end @headers['Set-Cookie'] = @cookies.map { |k,v| "#{k}=#{escape(v)}; path=/" if v != @k[k] } - [nil] end # accessor for @session. Please use session and # never @session directly. def session @session end end class Session < ::ActiveRecord::Base serialize :data def []=(k, v) # :nodoc: self.data[k] = v end def [](k) # :nodoc: self.data[k] rescue nil end RAND_CHARS = [*'A'..'Z'] + [*'0'..'9'] + [*'a'..'z'] # Generates a new session ID and creates a row for the new session in the database. def self.generate cookies rand_max = RAND_CHARS.size sid = (0...32).inject("") { |ret,_| ret << RAND_CHARS[rand(rand_max)] } sess = Merb::Session.create(:sess_id => sid, :data => MerbHash[]) cookies[:sess_id] = sess.sess_id sess end # Gets the existing session based on the camping_sid available in cookies. # If none is found, generates a new session. def self.persist cookies if cookies[:sess_id] session = Merb::Session.find_by_sess_id cookies[:sess_id] end unless session session = Merb::Session.generate cookies end session end end end