About

James Golick

James Golick's software experience ranges from artificial intelligence to web front-end and JavaScript development. Most recently, James has fallen back in love with web development thanks to Ruby on Rails.

Since discovering Rails, James has become a prolific contributor to its open source ecosystem. He is the author of several popular plug-ins and gems, and a contributor to countless others, including the framework itself.

James is an advocate for well-written, well-tested code and he blogs regularly about the practice of developing software. He speaks regularly at software development conferences and user groups. James is a partner in Nine Lives, Inc.

Latest Tweets

follow me on Twitter

James on the Web

Introducing has_browser: Parameterized browse interfaces for your AR models.

May 19 2008

Pretty soon after starting to use has_finder, I needed to write a browse interface. That is, given a set of parameters, return all the models that match. With has_finder, it is possible to compartmentalize those parameters in to small chunks, each with names that make sense in your model's domain. You can then chain them together to get their combined scope. The only problem iswas calling them when you aren't aware, in advance, of which finders need to be called.

Having had this problem a few times, and being sick of solving it over and over again, I decided to extract a general solution from a project I'm working on.

has_browser

It's a simple plugin, with a simple syntax. Using the canonical blog example, let's imagine we want to create a browse interface to posts. We'd want the user to be able to browse by category, author, or tags, but not to be able to access any of the other finders on the Post model for obvious security reasons. To set up has_browser, we'd do something like this:

has_browser :category, :tags, :author

Then, assuming the has_finders are already written, the posts can be browsed as follows:

Post.browse(:category => 'Testing', :tags => 'activerecord', :author => 'james')

In that example, each of the finders requires an argument; has_browser also supports finders that don't. As long as the argumentless finder is present in the browse hash, it will be called:

has_browser :category, :tags, :author, :without_args => [:order_by_date, :order_by_number_of_comments]

Post.browse(:category => 'Testing', :tags => 'activerecord', :author => 'james', :order_by_number_of_comments => 'true')

Browse can also be called from association_proxies. For a multi-blog platform, we could easily restrict browsing of posts to the current blog:

@blog.posts.browse(:category => 'Testing', :tags => 'activerecord', :author => 'james', :order_by_number_of_comments => 'true')

Since has_browser returns the same proxy as has_finder, it is possible to further restrict the results of a browse by chaining finders after the browse call. With our blog, for example, we'd probably want to restrict browsing to published posts.

@blog.posts.browse(:category => 'Testing', :tags => 'activerecord', :author => 'james', :order_by_number_of_comments => 'true').published

Note: It is not possible to chain finders before the browse call.

Finally, like has_finder, has_browser is compatible with will_paginate out of the box.

Get It

Releases of has_browser will be available as a gem, which you can freeze in to your rails app (init.rb included):

$ sudo gem install has_browser

Development, of course, is at github.


Comments


blog comments powered by Disqus