Rails 3 request dispatch cycle - ruby-on-rails

I was looking at the rails 3 architecture in order to understand the process of dispatching a request . The whole process is quite simple. Application is a rack application which finally delegates its call message to the call method of ActionDispatch::Routing::RouteSet which dispatches appropriate action of necessary controller. It takes controller and action names from the hash stored in rack env by the key "action_dispatch.request.path_parameters".
So the question is: Who sets this hash? Who parses request uri and determines action and controller names?
I was not able to find this code. I see that during route configuration ActionDispatch::Routing::Mapper object is used to construct information about defined routes and stores it in ActionDispatch::Routing::RouteSet. But how this information is used during the request to find appropriate action and controller. Is rack also somehow involved here?

"action_dispatch.request.path_parameters" is stored as the constant ActionDispatch::Routing::RouteSet::PARAMETERS_KEY (actionpack/lib/action_dispatch/routing/route_set.rb)
PARAMETERS_KEY is used later on in that same file and passed into the constructer for ::Rack::Mount::RouteSet
Going to ::Rack::Mount::RouteSet source here: https://github.com/josh/rack-mount/blob/master/lib/rack/mount/route_set.rb#L22 you can see that attribute name is stored.
Same file, down in the call(env) method which is of course the Rack interface that will be called into, we see this line ( https://github.com/josh/rack-mount/blob/master/lib/rack/mount/route_set.rb#L147 ) where your env["action_dispatch.request.path_parameters"] attribute is actually set, and eventually returned back into the code you were investigating.
Hope this helps!

Related

How param works in rails views

I have an old app running in rails 2.3.5
In customizing, I stuck when i find a param keyword being used in views
i.e in views I can see stuffs like
unless params[:fee_collection].nil?
can someone explain to me in what context is param keyword used in rail views rather than controllers
params is a hash that contains parameters sent with the HTTP request.
You can access to this object as well from your controller or from a view. Although, the convention is to access to an instance variable (defined in your controller, e.g : #fee_collection = params[:fee_collection]) from your view.
The params variable stores a hash which contains the http parameters received in the request to this route (controller#action)
If you have a UserController with the show method, you should receive the param[:id] to identify the resource you're looking for.
If you want to send parameters, it would be either via url in a GET or a data payload on a POST request, on the most common cases.

Why should controllers use notify_airbrake over Airbrake.notify

In the Airbrake wiki, it says to use notify_airbrake in controllers instead of Airbrake.notify, but doesn't explain why. What is the benefit of using notify_airbrake in controllers and why should it not be used elsewhere?
notify_airbrake is just a helper method. You don't have to use it (feel free to use Airbrake.notify). However notify_airbrake attaches extra information to the notice (like current user, session, Rack environment, etc). With Airbrake.notify you will only send what you pass to the method.
This is the beauty of open source. You can look at the code and figure out how and why something is implemented the way it is.
Having said that, look at airbrake code, specifically controller_methods.rb file (https://github.com/airbrake/airbrake/blob/3033798f69d20706f13fc0e3d79572041e9c7205/lib/airbrake/rails/controller_methods.rb)
You can see that notify_airbrake method actually calls a variant of Airbrake.notify (Airbrake.notify_or_ignore) after it extracts some extra information automatically like session data, request url, request params etc which are only available in the controller context. If they didn't do it this way, we will have to extract that information manually in the controller and pass it along. It's only there to make our lives easier :)
My 2 cents.

How is the `flash` in Rails made global to an application?

I'm curious as to how Rails achieves this. I notice that you can access the flash variable globally in an app, but it isn't prefixed with an # or a $.
I can also see that there's a method for accessing the flash and there's also an initializer as well that will set #flash, but how is it that I can call flash as a local variable?
Session
Further to apneadiving's answer, the flash is part of the middleware stack (ActionDispatch::Flash). It's actually a non-persistent session cookie:
--
From the docs:
The flash is a special part of the session which is cleared with each
request. This means that values stored there will only be available in
the next request, which is useful for passing error messages etc.
Much in the same way that params works (on a per request basis), the flash variable is only populated with data from the previous request.
--
Middleware
If you take apneadiving's comment, you'll see that the flash is created through the middleware stack - meaning the local nature of the variable is only set for that particular request (much the same as params). This is why you can access / set a flash message in any controller - because it's defined higher up the "middleware stack" - it provides a scope which appears global
I'm sure someone like apneadiving can explain it better than me, but that's how I see it

Rack Rails : How do I save query string in a database

I am using Rack middle ware to intercept all requests to my rails app. I am checking for a particular parameter in the query string. If the request has the parameter, I need to extract its value and put it in a database to be processed later. Otherwise I let the normal course of action to continue. Any ideas how to implement it?
P.S : I have done the following already.
1) I can extract the value of my desired parameter through Rack and send it along with the response (For testing purposes only)
2) I have tried created a custom controller and call it from the rack, but I am hitting upon undefined method error everytime.
Any help will be appreciated.

what are the sequence of events that happen when you get a page

Im trying to get my head around the sequence of events that happen between when rails receives a get/post command and the page is served. I was just trying to map out the sequence myself and i realised i dont fully understand myself which scripts is even ran first so I'd like to clear it up in my head.
many thanks
jon
The request goes into the route matcher which parses the URL, parses the config/routes.rb and if the URL matches a route, it looks for a controller file whose name matches the controller part of the URL, (e.g. http://localhost/categories will look for a CategoriesController)
Then, one of two things happen:
If you're using a Rails restful route, the route matcher applies heuristics to figure out which of the 7 actions to call: a GET on a plural last part is mapped to index; a GET mapped to an ID-looking part after the plural is mapped to show (e.g. categories/1 or categories/something or categories/1-something); a POST to a plural last part is mapped to create; a PUT to an ID-looking part after the plural is mapped to update; a DELETE to the same URL is mapped to destroy; new and edit are mapped to GETs for categories/new & categories/edit.
If you have a custom action, you must have a method in your controller object of the same name.
The chosen action is executed and then Rails either renders the template/file/action specified in the render call within the action or it looks for a view file of the same name as the action and that ends with .html.erb (by default) in the app/views/ directory.
Simple.
Rails does quite a lot of things, a good way to get a decent overview is to read the "Action Controller Overview" document at rails guides: http://guides.rubyonrails.org/action_controller_overview.html
The basic structure is:
rack middleware
routing
filters
controller code
rendering
filters
But rails also does many things by itself to the request. It automatically determines what kind of response you want based on your accept headers, and/or if you manually specify which type of response you want with a file ending like /blog/1.xml. Rails also magically creates a nicely formatted params hash, parsing params like user[name]=foo to {:user => {:name => "foo"}}. Rails also has built-in exception handling and some nice stuff to prevent cross site request forgery and much more, so check out the Controller Overview for the lowdown on that.

Resources