The Large application.rb File.

Posted by Mike Blake Sun, 30 Jul 2006 18:26:07 GMT

Where?

A common phenomenon starting to appear in some larger Rails applications is a bloated application.rb file.

Why does this happen?

Most of the time, developers place methods here to avoid duplicating code. The application.rb file is a convenient bucket whose methods can easily be seen by all the controllers in the application. In addition, these methods can be exposed to all the views in the application by using the ‘helper_method’

helper_method :find_valid_ad

So now all the views can see the exposed methods as well. Since the Views now have access to the Controller methods, it’s easy to fall into the habit of asking it to retrieve model objects via these helper methods.

What’s the problem?

This results is what design guru’s call Low Cohesion. A class with low cohesion is a bloated class that does many unrelated things. A bloated application.rb file, or any bloated class for that matter, has four fundamental problems.

  1. Hard to comprehend
  2. Hard to reuse
  3. Hard to maintain
  4. Delicate; constantly effected by change.1

Solutions

Class Methods

Rails views can automatically access all of our Model classes. By writing class methods on these models , we can eliminate some unnecessary methods in application.rb . Class methods in Ruby are similar to static methods in Java in that you don’t need an instance of the object to access the method.


So where should the extra method in application.rb live? The trick is to take a look at what the shared method in application.rb is returning. Is it returning an array of Model objects that are all of the same type? It’s better off living in that Model’s class file. If it returns a single instance of that Model, it’s an instance method. If it returns an array of that type, it’s a class method.


For the find_valid_ad method mentioned above, we can now make it a class method in the Ad model.

class Ad < ActiveRecord::Base

  def Ad.valid_ads
    # ... code from the old find_valid_ads method here
    # ...
    Ad.find_all_by_is_valid(true)    
    # ...
  end

end

Rails provides lots of flexibility in communicating between the Model , View and the Controller, so this line of code in the view

<%   find_valid_ads{ |ad| %>
  <%= ad.name %><br>
<% } %>

becomes

<%   Ad.valid_ads{ |ad| %>
  <%= ad.name %><br>
<% } %>

We’ve now eliminated an entire method from the application.rb file.

The MVC Triangle

The important thing to remember with MVC is that The View can communicate directly with the Model. Most web MVC frameworks encourage developers to think like this:

  +------+      +----------+      +--------+             
  | View | <--> |Controller| <--> | Model  |
  +------+      +----------+      +--------+

Rails developers can think like this:

               +--------+
               | Model  |
               +--------+
              /\        /\
              /          \
             /            \
            /              \
      +--------+       +----------+
      |  View  | <---> |Controller|
      +--------+       +----------+

Rails encourages well organized code writing and highly cohesive classes. With that in mind it’s easy to spot a class that is becoming unusually large. Typically the first one to get bloated is the application.rb file. Fortunately, this problem is easily fixed. Using common sense we can delegate responsibility to a more appropriate class.

Applying UML and Patterns, Larman, p203

Posted in  | 1 comment

Comments

  1. http://railhouserock.wordpress.com said 90 days later:

    Thanks for the discussion about helpermethod and how it can be abused. AWDwR gives it only a quick mention, and I'm not quite experienced enough to get much leverage out of the gemserver docs yet... :)

(leave url/email »)

   Preview comment