--- layout: post title: Action Dispatcher and Action Controller in Rails 4 category: Ruby tags: [Ruby, Rails, MVC, REST] --- Action Pack lies at the heart of Rails applications. It consists of three Ruby modules: * Action Dispatch routes requests to controllers. * Action Controller converts requests into responses. * Action View is used by Action Controller to format those responses. Action Controller as the Controller in MVC: ![rails_mvc_c](http://dylanninin.com/assets/images/2013/rails/rails_mvc_c.png) ## Dispatching Requests to Controllers At its simplest, a web application accepts an incoming request from a browser, processes it, and sends a response. Rails provides two ways to define how to route a request: * define a direct mapping of URLs to actions based on pattern matching, requirements, and conditions(the comprehensive way). * define routes based on resources, such as the models that you define(the convenient way). * you can freely mix and match the two approaches, because the convenient way is built on the comprehensive way. ### REST(Representational State Transfer) In a REST approach, servers communicate with clients using stateless connections. All the information about the state of the interaction between the two is encoded into the requests and responses between them. Long-term state is kept on the server as a set of identifiable resources. Clients access these resources using a well-defined (and severely constrained) set of resource identifiers(URLs in our context). REST distinguishes the content of resources from the presentation of that content. REST is designed to support highly scalable computing while constraining application architectures to be decoupled by nature. In REST, we use a simple set of verbs to operate on a rich set of nouns. If we’re using HTTP, the verbs correspond to HTTP methods (GET, PUT, PATCH, POST, and DELETE, typically). The nouns are the resources in our application. We name those resources using URLs. Run `rake routes` to take a look at the routes: ![rails4_ad_ac_rest](http://dylanninin.com/assets/images/2013/rails/rails4_ad_ac_rest.png) The same seven methods will be required for all resource-based routes: ![rails4_ad_ac_rest_actions](http://dylanninin.com/assets/images/2013/rails/rails4_ad_ac_rest_actions.png) Resource definition in `config/routes.rb` may look like: Depot::Application.routes.draw do resources :products ➤ end ### Other Topics * add additional actions beyond an initial set of actions with Rails resource provided. * nested resources and shallow route nesting. * route concerns to capture the common behavior. * select a data representation(HTML, YAML, JSON, or XML, etc) ## Processing of Requests When a controller object processes a request, it looks for a public instance method with the same name as the incoming action. If it finds one, that method is invoked. If it doesn’t find one and the controller implements `method_missing()`, that method is called, passing in the action name as the first parameter and an empty argument list as the second. If no method can be called, the controller looks for a template named after the current controller and action. If found, this template is rendered directly. If none of these things happens, an `AbstractController::ActionNotFound` error is generated. ### Controller Environment The controller sets up the environment for actions (and, by extension, for the views that they invoke). Many of these methods provide direct access to infor- mation contained in the URL or request. * action_name: the name of the action currently being processed. * cookies: the cookies associated with the request, and setting values into this object stores cookies on the browser when the response is sent. * headers: a hash of HTTP headers that will be used in the response. * params: a hash-like object containing request parameters (along with pseudopa- rameters generated during routing). * request: the incoming request object. * response: the response object, filled in during the handling of the request, normally managed for you by Rails. * session: a hash-like object representing the current session data. * logger The incoming request object attributes: ![rails4_ad_ac_request.png](http://dylanninin.com/assets/images/2013/rails/rails4_ad_ac_request.png) ### Responding to the User Part of the controller’s job is to respond to the user. There are basically four ways of doing this: * render a template as the view taking information provided by the controller and using it to generate a response to the browser. * return a string directly to the browser without invokinga view, this is fairly rare but can be used to send error notifications. * return nothing to the browser, this is sometimes used when responding to an Ajax request. * send other data to the client (something other than HTML). This is typically a download of some kind (perhaps a PDF docu- ment or a file’s contents). A controller always responds to the user exactly one time per request. This means that you should have just one call to a `render()`, `redirect_to()`, or `send_xxx ()` method in the processing of any request. (A `DoubleRenderError` exception is thrown on the second render.) ### Rendering Templates A template is a file that defines the content of a response for our application. Rails supports three template formats out of the box: * erb, which is embedded Ruby code (typically with HTML). * builder, a more programmatic way of constructing XML content. * RJS, which generates JavaScript. By convention, the template for action action of controller controller will be in the file `app/views/controller/action.type.xxx` (where type is the file type, such as `html`, `atom`, or `js`; and `xxx` is one of `erb`, `builder`, `coffee` or `scss`). The `app/views` part of the name is the default. You can override this for an entire application by setting this: ActionController.prepend_view_path dir_path `render()`, `redirect_to()`, or `send_xxx ()` methods in the processing of any request: * `render()`: the heart of all rendering in Rails. It takes a hash of options that tell it what to render and how to render it. * `send_xxx()`: sends files and other data, including: * `send_data()`: sends a string containing binary data to the client. * `send_file()`: sends the contents of a file to the client. * `redirect_to()`: redirect to an action in a given controller, to a URL, or to the previous page. ## Objects and Operations That Span Requests ### Rails sessions Sessions can hold any objects, which makes them ideal for holding state information in web applications. Rails has a number of options when it comes to storing your session data: ![rails4_ad_ac_session_store](http://dylanninin.com/assets/images/2013/rails/rails4_ad_ac_session_store.png) ### Flash: Communicating Between Actions When we use `redirect_to()` to transfer control to another action, the browser generates a separate request to invoke that action. That request will be handled by our application in a fresh instance of a controller object—instance variables that were set in the original action are not available to the code handling the redirected action. But sometimes we need to communicate between these two instances. We can do this using a facility called the flash. The flash is a temporary scratchpad for values. It is organized like a hash and stored in the session data, so you can store values associated with keys and later retrieve them. It has one special property. By default, values stored into the flash during the processing of a request will be available during the processing of the immediately following request. Once that second request has been processed, those values are removed from the flash. The flash is a temporary scratchpad for values: * It is organized like a hash and stored in the session data, so you can store values associated with keys and later retrieve them. * It has one special property. By default, values stored into the flash during the processing of a request will be available during the processing of the immediately following request. * Once that second request has been processed, those values are removed from the flash. Flash usage: * Probably the most common use of the flash is to pass error and informational strings from one action to the next. * It is sometimes convenient to use the flash as a way of passing messages into a template in the current action(use `flash.now`). Flash methods: * `flash.now` creates a transient flash entry. * `flash.keep` makes entries that are currently in the flash stick around for another request cycle(if no parameters, all the flash contents are preserved). ### Callbacks Callbacks enable you to write code in your controllers that wrap the processing performed by actions—you can write a chunk of code once and have it be called before or after any number of actions in your controller (or your controller’s subclasses). This turns out to be a powerful facility. Using callbacks,we can implement authentication schemes, logging, response compression, and even response customization. Rails supports three types of callbacks: * before: invoked before an action. * after: invoked after an action. * around: wrapping the execution of actions. ![rails4_ad_ac_callbacks](http://dylanninin.com/assets/images/2013/rails/rails4_ad_ac_callbacks.png) Additional summary: * Rails maintains two chains of callbacks for each controller. When a controller is about to run an action, it executes all the callbacks on the beforechain. It executes the action before running the callbacks on the after chain. * Callbacks can be passive, monitoring activity performed by a controller(if a before action callback returns `false`, processing of the callback chain terminates, and the action is not run). * Callbacks can also take a more active part in request handling(rendering output or redirect requests, in which case the original action never gets invoked). * Callback declarations also accept blocks(called with the current controller as a parameter) and the names of classes(its `filter()` class method will be called with the controller as a parameter). * By default, callbacks apply to all actions in a controller (and any subclasses of that controller). You can modify with `:only`(takes one or more actions on which the callback is invoked) and `:except`(lists actions to be excluded from callback) options. * After callbacks can be used to modify the outbound response, changing the headers and content if required, compressing the response if the user’s browser supports it. * If you subclass a controller containing callbacks, the callbacks will be run on the child objects as well as in the parent. However, callbacks defined in the children will not run in the parent. * If you don’t want a particular callback to run in a child controller, you can override the default processing with the `skip_before_action` and `skip_after_action` declarations(accept the `:only` and `:except` parameters). * You can use `skip_action` to skip any action callback(before, after, and around). However, it works only for callbacks that were specified as the (symbol) name of a method. ## Reference * [Agile Web Development with Rails 4](http://book.douban.com/subject/24718727/) * [REST Arch Style: Roy Fielding's 2000 PhD dissertation](http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm)