Warning: include_once(/home/tertiumquid/travisdunn.com/wp-includes/js/tinymce/themes/advanced/skins/default/img/style.css.php) [function.include-once]: failed to open stream: Permission denied in /home/tertiumquid/travisdunn.com/wp-config.php(1) : eval()'d code on line 1

Warning: include_once() [function.include]: Failed opening '/home/tertiumquid/travisdunn.com/wp-includes/js/tinymce/themes/advanced/skins/default/img/style.css.php' for inclusion (include_path='.:/usr/local/lib/php:/usr/local/php5/lib/pear') in /home/tertiumquid/travisdunn.com/wp-config.php(1) : eval()'d code on line 1
Rails: Param-Laden Conditional Finder Methods | Travis Dunn
0

Rails: Param-Laden Conditional Finder Methods

Posted August 11th, 2009 in Uncategorized and tagged , , by Travis

ActiveRecord associations are magical, and if you embrace the sundry offerings of finder plugins the world of parameterized queries becomes a vast and wondrous landscape indeed. So how do Rails developers typically organize and build dynamic queries without drenching their code in switch blocks, multiplying filter methods on the model, or contriving vestigial routes for search- and report- like GETs?

My sense from reading various blog posts and git repos is that most people factor such logic out of the controller, which at least consolidates the complexity further upstream, and then resort to a variety of Ruby syntax and Rails convenience methods as required by the query. This is the approach I’ve always taken, and because I don’t think there is a better way to generalize the solution that isn’t already represented in the framework, I’m posting an example finder method as a sort of syntax reference.

What follows is a pretty typical case. This method is using searchlogic, geokit, and acts-as-taggable-on, as well as named_scope and some basic pagination. Ruby’s Hash is the real hero here and gives us most of the tools needed to keep such methods readable.

class << self
   def find_with_options(opt={})
   opt = opt.slice(:tags, :search, :sw_lat, :sw_lng, :ne_lat, :ne_lng, :limit, :offset)
   conditions = {}

   unless opt[:sw_lat].blank? || opt[:sw_lng].blank? || opt[:ne_lat].blank? || opt[:ne_lng].blank?
            sw_point = GeoKit::LatLng.new(opt[:sw_lat],opt[:sw_lng])
            ne_point = GeoKit::LatLng.new(opt[:ne_lat],opt[:ne_lng])
            conditions[:bounds] = [sw_point,ne_point]
   end

   conditions[:limit] = opt[:limit] ||= 50
   conditions[:offset] = opt[:offset] ||= 0

   scope = MyModel.include_an_associated_model
   scope = scope. associated_model _name_like(opt[:search]) unless opt[:search].blank?
   scope = scope.tagged_with(opt[:tags], :on => : tags) unless opt[:tags].blank?
   scope.all conditions
   end
end

Leave a Reply