Bad Dinosaur!

You Should Check This Out

CollegeJobConnect | Better Undergraduate Recruiting

Saturday, January 30, 2010

Don't Be A Fatty (Rails Controller)

(why you might care is my effort to help you make your decision to read this posting more efficient. WYMC is a quick summary and the high level questions I pose so you can determine if you'd like to read the whole article or not)
During a project's build, I decided to use the ApplicationController / session store to implement a high level, expandable filtering system. Design decision allowed quick development, but fattened up the ApplicationController and feels more like "The PHP Way" rather than "The Rails Way". Critiques of the currently implemented system and viable alternatives requested.

As some of you know, I accidentally bid on a consulting project a month or so ago and was awarded the mandate. Oops. One of the major requirements for this application was a filtering system that was user specific and semi-persistent (filters needed to hang around while the user was logged in, despite jumping around to different views). The filtering system needed to be easily added to a model / view as per the client's request and adding / removing which criteria were "filterable" needed to be immensely flexible (as it was not set in stone what dimensions we would want to filter upon for any of the given models). The number of total users using this application at any one time would be very low. Oh yeah, and all this needed to be built super fast.

With an eye on speed of initial development and ease to quickly and seamlessly expand / extend down the line I set off down the coding road. I ended up with the following work flow for the filtering system. I look to you, internet, for feedback.

I leveraged the ApplicationController and a before_filter to scan for any new filters being added or removed via the params hash on each page load (ApplicationController#handle_filters). This method either adds or removes a specified filter to or from the session hash, for example:

session["#{controller_name.downcase.singularize}_filters"].push( params[:filter_to_add] )

I thought about associating the filters with the currently logged in User, but this seemed a bit overkill, especially given my time constraint. The session, while somewhat bush league, seemed like a good fit.

Next I created a shared/filter_controls partial that can be dropped into any model's view, which renders a standard filter control with a pre-populated list of acceptable filters for the current controller / model.

Now filters can be added / removed from the session and a nice UI component is readily available. How do they actually trim down the items returned? To make a model "filterable" I added a #find_all_matching method and pass it the model-specific session key (Dinosaur.find_all_matching(session[:dinosaur_filters]). This method finds all if the passed filter hash is blank, otherwise it processes the filters and sets up the appropriate set of conditions to apply to the query.

Positives: quick build; dead simple to add a filter; ApplicationController handles where to put the specified filter based upon the current controller; filters are semi-persistent; making a model "filterable" just requires adding a custom method to process any associated filters.

Negatives: Feels more like "The PHP Way" rather than "The Rails Way"; Fat ApplicationController:

Gross. Look at all that meat.

Given the current system, where are areas of improvement? Given more time to develop, what would be a superior set up?


Post a Comment

Post a comment ...