MetaSearch, MetaWhere, and Rails 3.0.3

Comments

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.

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