Confounding URL typists since 2007.

MetaSearch, MetaWhere, and Rails 3.0.3

Posted by Ernie on November 21, 2010 at 7:50 pm

Well, Rails 3.0.3 is out, and it includes all of that ARel 2.x goodness I was rambling about a few weeks ago. Anyway, I just wanted to make a quick post here because I haven’t gotten around to updating docs with details on how to use all the new toys.


  • You can say :association.inner and :association.outer in your joins, to force a LEFT OUTER JOIN without resorting to includes.
  • Having clauses allow MetaWhere conditions now.
  • You can call SQL functions with :function_name.func() and (if symbols are enabled) :function_name[].

Extra credit:
If you’re really adventurous, you can try the experimental “ActiveRecord values” branch out. Something that has bugged me for a while is that you can’t say stuff like Post.joins(:comments).where(:comments => ), or Comment.where(:post => ). With this branch, you can. Here are some samples from the tests:

Developer.where(:company => Company.first)
=> SELECT "developers".* FROM "developers" WHERE "developers"."company_id" = 1
# Polymorphic belongs_to
Note.where(:notable => Developer.first).to_sql
=> SELECT "notes".* FROM "notes" WHERE "notes"."notable_id" = 1
   AND "notes"."notable_type" = 'Developer'
# Polymorphic has_many
Developer.joins(:notes).where(:notes => Note.first).to_sql
=> SELECT "developers".* FROM "developers"
   INNER JOIN "notes" ON "notes"."notable_id" = "developers"."id"
   AND "notes"."notable_type" = 'Developer'
   WHERE "notes"."notable_id" = 1 AND "notes"."notable_type" = 'Developer'
# has_and_belongs_to_many
Developer.joins(:projects).where(:projects => Project.first).to_sql
=> SELECT "developers".* FROM "developers"
   INNER JOIN "developers_projects"
   ON "developers_projects"."developer_id" = "developers"."id"
   INNER JOIN "projects"
   ON "projects"."id" = "developers_projects"."project_id"
   WHERE "projects"."id" = 1

You can also supply an array of ActiveRecord objects, as well. It even works with polymorphic belongs_to:

dev1 = Developer.first
dev2 = Developer.last
project = Project.first
company = Company.first
Note.where(:notable => [dev1, dev2, project, company]).to_sql
=> SELECT "notes".* FROM "notes"
   WHERE (((("notes"."notable_id" IN (1, 8) AND "notes"."notable_type" = 'Developer')
   OR ("notes"."notable_id" = 1 AND "notes"."notable_type" = 'FixedBidProject'))
   OR ("notes"."notable_id" = 1 AND "notes"."notable_type" = 'Company')))


  • You can override the key for search parameters that sort_link will use — just pass the :search_key option at the end of your call to
  • You can define your own custom sort scopes. Define scopes named “sort_by__asc” and “sort_by__desc” and sort_link , :name will work as you might expect.
  • Localization. First, for sort_link, it will localize the attribute names in the links it creates. More importantly, you can define your own localizations for form labels using the i18n key under meta_search.attributes, similarly to activerecord.attributes (under the model name). If one doesn’t exist here, MetaSearch will look under meta_search.predicates.predicate_name — the latter will localize the predicate name and use the AR localization for the attribute, if available. See lib/meta_search/locale/en.yml for an example. A big thanks to Marc-Antoine Duhaime for his donation in support of this functionality.

That’s about it! I’m excited about the updates, and I hope you find them useful!

Filed under Blog
Tagged as , ,
You can leave a comment, or trackback from your own site.