What does Sinatra :: Base.condition actually do?

I came across the sinatra method and puzzled by how he works.

I have a code:

def auth user condition do redirect '/login' unless user_logged_in? end end 

Which checks if the user is registered for specific routes, example route:

 get '/', :auth => :user do erb :index end 

user_logged_in? method user_logged_in? defined in a supporting file in the lib directory of the project:

 def user_logged_in? if session[:user] @user = session[:user] return @user end return nil end 

So the question is: How does the condition block know what session[:user] contains when the session[:user] parameter is not yet set on the get '/' route?

The condition method is defined on the next GitHub page: sinatra base condition method Thank you.

+6
source share
2 answers

When you define a route, the key of each member of the options hash is called as a method, with the value passed as arguments .

So, when you do get '/', :auth => :user do ... , the auth method is called with the argument :user . This in turn calls the condition method with a block.

The condition method is actually the one above, where you refer to which is its use. It looks like this:

 def condition(name = "#{caller.first[/`.*'/]} condition", &block) @conditions << generate_method(name, &block) end 

The generate_method method converts the block into a method with the given name, and then this method is stored in the @conditions array, the contents of @conditions then saved with the route definition, and @conditions is cleared for the next route definition.

At this point, the code block passed to condition was not executed. In fact, it was saved later.

When a real request arrives, if the request path matches the route, then each condition associated with this route is fulfilled to check if it is satisfied. In this example, is it when redirect '/login' unless user_logged_in? runs first, so session will be configured and session[:user] will be available (or not if they are not logged in).

It is important to understand that when you pass a block to a method, the code in that block does not have to be called right away. In this case, the code in the block is called only upon receipt of the actual request.

+4
source

Because Sinatra is responsible for calling both condition methods and route methods. Therefore, it should be safely assumed that no matter what is set when your route method is executed, it is also set when your condition is met.

Take a look at the code starting here : conditions are invoked one by one; if all conditions match, then the block is called. Nothing happens between the validation conditions and the block invocation: they basically work with the same context.

+2
source

Source: https://habr.com/ru/post/906540/


All Articles