Sunday 1 February 2015

Filters in Rails


 Filters are essentially callback methods that are run before, after, or “around” a controller action.

  • Before filter methods are run before a controller action and therefore may halt the request cycle. A common before filter is one which requires a user to be logged in for an action to be performed.
  • After filter methods are run after a controller action and therefore cannot stop the action from being performed but do have access to the response data that is about to be sent to the client.
  • Around filter methods are “wrapped around” a controller action. They can therefore control the execution of an action as well as execute code before and/or after the action is performed.

For example, in a website where changes have an approval workflow, an administrator could be able to preview them easily with an around filter as follows:





















Note that an around filter also wraps rendering. In particular, in the example above, if the view reads from the database (e.g., via a scope), it will do so within the transaction and thus present the data to preview. You can also choose not to yield and build the response yourself, in which case the action will not be run.
The order of execution is a bit tricky and is important to understand clearly. Filter methods execute in the following order:
  1. Before filter methods, in order of definition.
  2. Around filter methods, in order of definition.
  3. After filter methods, in reverse order.
Also, because of the way Ruby instantiates classes, the filter methods of a parent class’ before will be run before those of its child classes. 

Saturday 3 January 2015

Redirecting to Custom 404 and 500 Pages in Rails

Rails bundles default 404 (file not found), 422 (unprocessable entity), and 500 (internal server error) pages into every newly generated application. While they get the job done, these pages are pretty bland, so in this post I’ll show you how to update them to suit the design of your application. As an example, here’s what the default 404 page looks like:

If you open any Rails application lacking custom error pages, you’ll find this 404 page in the file public/404.html. Therefore the easiest possible solution to creating custom error pages would be to simply edit each of these files as desired. Once updated, you can view them in your development environment by navigating directly to them (error pages aren’t shown by default in Rails’ development environment when an error occurs; more on this later in the post). For instance to see the custom 404 page you’d navigate to http://0.0.0.0:3000/404.html.

While you could get away with directly modifying the 404.html, 422.html, and 500.html pages, an alternative approach exists that provides more flexibility in terms of how these errors are handled and eliminates the need to potentially duplicate any layout markup that is otherwise automatically injected into your views. Even better, this alternative approach is accomplished in a few simple steps. Start by modifying your application.rb file, adding the line config.exceptions_app = self.routes. For instance here’s what the MyRailsApp config/application.rb file looks like after adding this line:

module MyRailsApp
  class Application < Rails::Application
    config.exceptions_app = self.routes
  end
end

This setting tells Rails to allow any exceptions to be handled by another application, which is in this case the application router.
Next, add the following three lines to the bottom of your config/routes.rb file:
match '/404', to: 'errors#file_not_found', via: :all
match '/422', to: 'errors#unprocessable', via: :all
match '/500', to: 'errors#internal_server_error', via: :all
The match method is used to match a URL to one or more routes. It’s a bit more flexible than for instance the get method because you can configure it to be triggered in conjunction with any matching route and HTTP method as opposed to for instance just a route matching the get method. You can pass specific HTTP methods into the via option, however we want to match routes in conjunction with any HTTP method, and so I’ve passed all into via.
Save these changes and next generate the errors controller and associated actions referenced in these newly created routes:
$ rails g controller Errors file_not_found unprocessable internal_server_error
Restart your Rails server, and navigate to some random nonexistent page. You’ll see that your development server does not respond as desired. This is because you need to tell Rails to no longer dump detailed debugging information to the HTTP response, a feature that is logically desired during the typical debugging process. You can do this by adding the following line to your config/environments/development.rb file: 
 config.consider_all_requests_local = false
 After having added this line, restart your Rails server again, navigate to a non-existent URL, and you should see the file_not_found default view!

With the dynamic error handlers implemented, you have the convenience of allowing the default layout to be wrapped around the views, and can optionally implement more advanced handlers. For instance you can take advantage of various request methods to retrieve parts of the request (the requested page, parameters, etc) and build in logic that suggests possible desirable destinations!

Thursday 1 January 2015

fat model, skinny controller in Ruby on Rails

What is the “fat model, skinny controller” approach? Discuss some of its advantages and pitfalls, as well as some alternatives.

 

“Fat model skinny controller” is an MVC-based Rails design pattern.

MVC is itself a software design pattern that separates a system into three separate and distinct layers; namely, Model, View, and Controller. MVC strives to ensure a clean separation between each of its layers through clearly defined APIs. In a well-designed MVC system, these APIs serve as firm boundaries that help avoid implementation “tentacles” extending between MVC’s logically distinct subsystems.

The “Fat model skinny controller” design pattern advocates placing as much logic as possible in the Model for (a) maximum reuse and (b) code that is easier to test.

That said, a common pitfall for Rails developers is to end up with “overly bloated” models by adhering too blindly to the “fat model, skinny controller” paradigm. The infamous User model is a prime example of this. Since many Rails apps are about the user entering data into the system, or sharing information with their friends socially, the user model will often gain more and more methods, eventually reaching the point where the user.rb model becomes bulky and unmanageable in size.

A few key alternatives worth considering include:
  • Use of other objects: Extract functionality out of models into other objects (such as Decorators or Service objects)
  • Hexagonal architecture for Rails: Employ a hexagonal architecture that views the application as a hexagon, each side of which represents some sort of external interaction the application needs to have.
  • DCI (Data Context Interaction): Instead of focusing on individual objects, focus on the communication and interactions between data and its context.