MetaSearch, MetaWhere, and Rails 3.0.3
CommentsWell, 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.
MetaWhere
- 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 => @comment), or Comment.where(:post => @post). With this branch, you can. Here are some samples from the tests:
#belongs_to
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')))
MetaSearch
- 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 Model.search
- You can define your own custom sort scopes. Define scopes named “sort_by__asc” and “sort_by__desc” and sort_link @search, :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!
comments powered by Disqus