Multiple before and after blocks
samjohnduke opened this issue · 6 comments
Just want to say first that I love this little framework, I've used celluloid as library before and this just really makes sense.
I'm building a little messaging app and I have created a few components like sessions and authentication, the problem is when I extracted them into a library I had no way to set them up before and after each request.
Because there is no rack and therefore no middleware I couldn't think of a way to wrap a request apart from before and after. I had a look at adding filters like sinatra has but I couldn't get the context for running the filter blocks right.
Maybe there is another way?
@samjohnduke thanks! i'm glad you like it
i've got a basic (very) start on more sinatra-like filters going on the 'filters' branch. please have a look:
https://github.com/kenichi/angelo/compare/filters
this is mostly a spike solution, but it does work... you can do something like this:
class FilterTest < Angelo::Base
before '/secret_area' do
# authenticate!
end
get '/' do
erb :index
end
get '/secret_area' do
erb :authed_user
end
end
thoughts? also, i'm interested in your "components like sessions". can you provide some examples of that?
Ah. That's a really cool way to program. Not seen anything like that in ruby before. It looks exactly like what I was after.
For context the components are similar to how you implemented the erb module. You include the module, it calls a registered method with the base context and then you add the necessary components onto the base.
module Session
def self.included? base
registered base
end
def registered app
app.before do
init_session request
end
app.after do
finalize_session
end
end
def init_session request
@session_key = fetch_session_key(request)
@session = SessionStore.new
end
...
end
As far as I can tell it's basically the same as sinatra without Angelo::Base having the register function call. It is a little less clean this way but it works. (except that it doesn't if you want to declare another before or after block elsewhere)
I'll extract the whole session gem and push it to git hub so it's available, but the codes not the greatest.
Here is the sessions gem I extracted - Angelo Sessions
@samjohnduke thanks! i will be looking further over the weekend...
@samjohnduke i added pattern matching in filters when using mustermann. from the branch, you can now do:
include Angelo::Mustermann
before '/user/:user_id/:relation' do
# access params[:user_id] and params[:relation] here
end
get '/user/:id/things' do
# params keys from before block are not accessible here
# params[:user_id] will be nil, but params[:id] will not be
end
This is how Sinatra behaves and it seems legit to me.
Also, out of curiosity, what parts/code/style do you mean by:
Ah. That's a really cool way to program. Not seen anything like that in ruby before.
Lastly, thanks for your interest! I got your angelo-sessions code working with this branch!
@kenichi Glad you got sessions working!
I think the blocks look good and will perform exactly as required. I will have a further look this weekend and see how it goes.
I was referring to binding a 'floating' instance method to the current caller before invoking it. I haven't done much meta programming in ruby and it's something I'm still trying to get my head around. But it looks really useful.