ActionController - Rails Internals Series - III05 Apr 2016 ActionController Rails
This is my third post of my Rails Internals series mainly focusing on ActionController library and its modules.
The ‘VC’ layer of the MVC paradigm is responsible for the handling incoming HTTP request and responding with any one of template formats HTML/XML/JSON/PDFs and much more. The view and controller layer of Rails are heavily interdependent on one another.
In Rails, ActionPack is the component/package in charge of VC layer of the application. ActionPack composes of several modules for different mechanisms. From API documentation,
Let’s dive deep into the controller layer.
Controllers in Rails are backed up by ActionController component. It receives request from the browser, fetch or save data in database and renders HTML output to the browser. All the controllers inherit from ApplicationController which in turn inherits from ActionController::Base class. Having ApplicationController gives us ability to configure things in one place and have the functionality available in all other controllers of the application. For example, adding features to ApplicationController like request forgery protection and authorizing the user before executing any controller actions are inherited by other controllers of the application. ActionController::Base provides us with number of helpful methods.
Categories of ActionController Methods
I would like to categorize the methods added by the ActionController for understanding purpose.
- Input category methods → request, params, session, cookie (if one available)
- Storage category methods → session, cookie, flash
- Filter category methods → before_action, after_action, around_action
- Output category method → response method, render, redirect methods
Note: params, session, cookie, flash methods work like a hash.
Action Controller methods in detail
Request accessor method of a controller points to request object which is instance of ActionDispatch::Request, associated with current request cycle. The request object has lots of properties/methods to get information about the request coming in from the client. Refer API documentation for all available Methods. For example,
request.url, request.method, request.request_method, request.path_parameters, request.query_parameters, request.request_parameters, request.body and so forth
All parameters from request (either query string from URL or POST data from form) are collected in params hash.
With each new request to server, the browser sends session cookie along with other cookies if it has any (session cookie and cookie was set in the previous request). We use session, cookie, flash objects provided by Rails to store small amount of data in browser cookie which is needed for further requests as HTTP is stateless protocol and does not persist the data between requests. session method is used to persist the data between the requests until the browser is closed. cookie method to persist until a specified expiration has been reached. flash method is used to persist the data until just the next request and cleared out in the next request(accessed in the view usually). All persisted data is accessed in our controller through session, cookie, flash hashes.
Controller communicates with the database and performs CRUD actions where necessary and stores the data from db in an instance variable for making it available to the view.
- Storage mechanism: Rails uses different storage mechanism to store data upto 4K to persist between requests. Refer API documentations
- ActionDispatch::Session::CookieStore - Stores everything on the client.
- ActionDispatch::Session::CacheStore - Stores the data in the Rails cache.
- ActionDispatch::Session::ActiveRecordStore - Stores the data in a database using Active Record. (require activerecord-session_store gem).
- ActionDispatch::Session::MemCacheStore - Stores the data in a memcached cluster (this is a legacy implementation; consider using CacheStore instead).
Filters are method to hook some behaviour on to the actions at very specific time (before_action, around_action, after_action). For example, A common “before” filter is one which authenticates the user for an action to be executed.
Response accessor method returns a response object which is instance_of ActionDispatch::Response, represents what is going to be sent back to the client. The response object is not usually used directly, but is built up during the execution of the action (i.e) when calling render and redirect methods without developer intervention. Response object holds the headers and document data to be sent back to user.
Rendering mechanism: Action Controller sends content to the user by calling rendering methods. Rendering happens automagically as the ActionController triggers ActionView which enables rendering the ERB templating. The controller uses instance variables to pass the objects to the view.
- Redirecting mechanism: After create, update and destroy action, we need to redirect to other action of the controller than just rendering a template. When redirect_to method is called, Rails uses HTTP status code 302, a temporary redirect, to tell browser to make next request to the URL mentioned in location header field of the HTTP response.
Play Time with ActionController methods
Below is the code I used to learn ActionController. I know its pretty big but still wanted to sample out here to get some idea.