Posts tagged with: "fetching"

Fetches: Bringing Your ActionController its Slippers

Mini

by Michael Bleigh

There is a piece of code that shows up more than 80% of the controllers that I write, and it goes a little something like this:

class UsersController < ApplicationController
  def user
    @user ||= User.find(params[:id])
  end
  helper_method :user
end

A simple memoization method to allow me to easily grab the parameter-referred user in all of my actions. If I’m using nested routes, that means I can write two, maybe three of these methods into a controller. I’m basically using slight variations on the same code 20 different times in an application. Since we live in a world that loves to be DRY, I thought, “I can do better.”

Fetches: Memoizing Your Parameter Record Retrieval

Fetches is a simple extension to ActionController that lets you simply define those kinds of fetch methods on a one-line command. For the example above, I can rewrite it like so:

class UsersController < ApplicationController
  fetches :user
end

That’s pretty useful! Not only can I call the “user” method from the controller, but it’s automatically helperized so that I can use the same call in my views. Of course, there are times when more advanced fetching is called for, say using a method other than find or storing to a different variable name. Let’s take a look at a slightly more complex example:

# assuming a route like /users/:user_id/articles/:id
class ArticlesController < ApplicationController
  fetches :user, :as => :author, :from => :user_id, :using => :find_by_login
  fetches :article
end

Now if I were to call “author” in any of my controller actions, it would be equivalent to User.find_by_login(params[:user_id]). Similarly, calling “article” is equivalent to Article.find(params[:id]). The “from” option can also take a Proc in case your fetching is not simply a parameter key:

class UsersController < ApplicationController
  fetches :user, :from => Proc.new{ |c| c.params[:user_id] || c.params[:id] }
end

The main advantages to fetches are brevity, clarity and DRYness. I’ve found that this method covers every use case for parameter-based fetching that I’ve needed, and as such provides a much simpler, more readable, and shorter way to fetch models for use in your controller and views.

Installation

Fetches is available as a gem as well as in traditional plugin format. To install
as a gem, add this to your environment.rb:

config.gem 'mbleigh-fetches', :source => 'http://gems.github.com', :lib => "fetches"

To install it as a traditional plugin:

script/plugin install git://github.com/mbleigh/fetches.git

Resources

The source is available on GitHub, the Acts As Community project is there for general discussion, and the Lighthouse is there for bugs and feature suggestions.

UPDATE: A commenter requested that the plugin be able to handle creation of new records in addition to fetching existing records. I have added in the :initialize option to do just this. Examples:

fetches :user, :initialize => true # initialize from params[:user]
fetches :user, :initialize => :author # initialize from params[:author]
fetches :user, :initialize => Proc.new{ |c| {:login => c.params[:login], :email => c.params[:email]} }
Comment | 

Words we've written view all blog posts »

Featured Article

Intridea at Lonestar Ruby Conference

by Renae Bair on August 18, 2010

For the third straight year in a row, senior-level developers from the Intridea team will be at the Lonestar Ruby Conference, on Thursday, August 26th, teaching students about Ruby. Students attending the Ruby Intrigue class will work with our Director of Mobile Development, Brendan Lim, our Director of Development, Adam Bair, and our Director of Research and Development, Pradeep Elankumaran. Continue reading »

Recent Blog Posts

FlockFeeds Launches From Node Knockout

by Intridea on August 30, 2010

Using NPM with Heroku Node.js

by Michael Bleigh on August 24, 2010

Fixing Common Bundler Problems

by Jerry Cheung on August 23, 2010