Comments (6)
This is a two-part issue:
First, Camping overrides the session entirely on each request (killing, for example, rack-flash's data). There's a simple fix for that: change line 408 of camping-unabridged.rb (and similarly in camping.rb) to
@env['rack.session'].merge! Hash[@state]
(essentially, replace assignment with merging). However, I am afraid this might cause trouble with old code - if somebody was using Hash#delete to remove entries from @state
, they wouldn't be removed now. Magnus - do we have a green light? ;)
Second, and worse, part, is that rack-flash uses some heavy metaprogramming just in order to define a flash
method in the app which uses it. While its magic might work for some frameworks (Sinatra is, interestingly, apparently special-cased), it doesn't for camping and raises an exception. Workaround to this is to use Rack::Flash, :helper => false
(and @env['x-rack.flash']
to access the notices) in Camping code, solution would be to get rack-flash guys to special-case Camping, too.
There's also third thing - Rack::Flash has to be used before you include Camping::Session
(due to internal order of calling middlewares being in reverse). This could possibly be changed to be more intuitive, but would require some rewiring in Camping.
from camping.
(Here's a tiny app using rack-flash, for testing: https://gist.github.com/1304573)
from camping.
Wow :=)
First
The problem is that, if you delete keys in the state
then rack.session
still has them and merge won't get rid of them! I stumbled across your idea and I think it is half the battle. I'll post my attempt in my next post.
Second
I noticed this. I have had to use @env['x-rack.flash']
to access the FlashHash and it's ugly but notice that this is what you have to do for vanilla Rack apps per the Rack-Flash documentation so I guess Camping is considered vanilla :( heh
Third
I think this is why there is some weird metaprogramming on Rack::Builder
in Rack-Flash in order to force it's way to the end of the middleware call chain, arguably their should be a Rack API for this (but what if two oh so special middlewares want to be on the tail end? Who wins?) Well spotted though. I have use
d it first in my app.
from camping.
Here is my attempt
# diff two Hashes, er two Hs
class Camping::H
def diff(other)
self.keys.inject({}) do |memo, key|
unless self[key] == other[key]
memo[key] = [self[key], other[key]]
end
memo
end
end
end
def initialize(env, m) #:nodoc:
.
.
# make a shallow copy
@_state = @state.clone
@cookies._p = self/"/"
end
def to_a
# what is the diff between cloned and new?
diff = @_state.diff(@state)
# remove vanished keys from session
diff.each {|k,v| @env['rack.session'].delete(k) }
# merge what is left
@env['rack.session'].merge! Hash[@state]
.
.
.
end
This solution seems to work for me with adding and deleting state
entries. And seems to play nice wit Rack-Flash once you use it in the right order use( Rack::Flash, :flash_app_class => self, :accessorize => [:notice, :alert])
the first line in your app. It's verbose and slow but works for me (I think?).
from camping.
rewrite:
module CampingFlash
def self.included(base)
Camping::H.class_eval do
def diff(other)
self.keys.inject({}) do |memo, key|
unless self[key] == other[key]
memo[key] = [self[key], other[key]]
end
memo
end
end
end
end
def to_a
# overwrite the session with how @state is now
# depeding on whether diff is defined for H or not
if @state.respond_to? :diff
diff = @_state.diff(@state)
diff.each {|k,v| @env['rack.session'].delete(k) }
@env['rack.session'].merge! Hash[@state]
else
@env['rack.session'] = Hash[@state]
end
.
.
.
end
def initialize(env, m) #:nodoc:
.
.
.
@_state = @state.clone
@cookies._p = self/"/"
end
end
from camping.
This rewrite means that we only need to touch Camping a tiny little bit. The rest remains the same from the previous post in this issue.
# this goes into a possible module CampingFlash
def to_a #:nodoc:
if @state.respond_to? :diff
diff = @_state.diff(@state)
diff.each {|k,v| @env['rack.session'].delete(k) }
end
super
end
# this is the only change to Camping
def to_a #:nodoc:
# overwrite the session with how @state is now
# depeding on whether diff is defined for H or not
if @state.respond_to? :diff
@env['rack.session'].merge! Hash[@state]
else
@env['rack.session'] = Hash[@state]
end
.
.
.
end
# this goes into a possible module CampingFlash
def initialize(env, m) #:nodoc:
super(env,m)
@_state = @state.clone
end
from camping.
Related Issues (20)
- New Spec for Routing HOT 14
- Add Zeitwerk Autoloading, Establish loading procedure.
- How to return return json and pdf. HOT 1
- Camping Audit
- Write Config.kdl guide
- Use KDL as the settings/config file thingy HOT 1
- Add Rack 3.0 Linter to Tests
- Officially support Windows again
- Write Tests for generator HOT 1
- Rename Master Branch to Main (Again) HOT 1
- Fix Reloader HOT 3
- Gem dependencies are not fully documented in the ReadMe HOT 11
- Camping Server isn't Properly Tested.
- Add simpler DSL support for straight up mapping requests to a camping app.
- Add Markaby back as a dependency
- Add RAKE task to release new gem
- Make passkeys the default authentication option HOT 2
- Getting error when trying out camping book section 02 on models HOT 1
- RubyGems page still lists camping.rubyforge.org as homepage HOT 3
- Sub directories in Apps won't let you redefine URLs without being sad
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from camping.