Any interest in inferred joins?

I've been fiddling around a bit with the concept of adding "inferred
join" capabilities to a gem I've been working on.

The general idea, to me, is one that feels so "Rails-like" (as in,
principle of least surprise) that I was kind of surprised it wasn't
already in.

The goal: If you're selecting Articles, but the selection criteria are
based on stuff associated to articles, I shouldn't need to think about
what needs to be joined in advance if I don't want to. I should be
able to do...

Article.where(
  :title => 'Hello world',
  :comments => {
    :body => 'First post!',
    :moderations => [
      :value < 0
    ]
  }
)

...and end up with something like this:

SELECT "articles".*
FROM "articles"
  INNER JOIN "comments" "mw_infer_comments"
    ON "mw_infer_comments"."article_id" = "articles"."id"
  INNER JOIN "moderations" "mw_infer_moderations"
    ON "mw_infer_moderations"."comment_id" = "mw_infer_comments"."id"
WHERE ("articles"."title" = 'Hello world')
  AND ("mw_infer_comments"."body" = 'First post!')
  AND ("mw_infer_moderations"."value" < 0)"

I have this working, in rough form, at http://github.com/ernie/meta_where/tree/inferred_joins
(the relevant code is in meta_where/lib/inferred_join_dependency.rb
and query_methods.rb). It's a bit kludgy at the moment, but this is
only my first stab at it.

I'm just curious if:

a. Anyone on core would be interested in something like this. If not,
I'm happy to maintain it in MetaWhere, as well, provided....
b. Anyone has suggestions for an improved implementation.
JoinDependency, and the association code in general, is kind of a pain
to work around right now. I suspect that bypassing JoinDependency
altogether for an alternative implementation would yield performance
and readability improvements.

Thanks!

I suppose you could override Relation#build_where

    def build_where(*args)
      if result = super
        case args.first
        when Hash
          # Figure out table names from *args here and add them to
join_values or something
        else
          super
        end
      end
    end

I'm not very sure about the feature itself though. There are times
when you may want to eager load the joined table.

Definitely looks like a cool idea for a plugin though. You should keep
working on it.

I suppose you could override Relation#build_where

   def build_where(*args)
     if result = super
       case args.first
       when Hash
         # Figure out table names from *args here and add them to
join_values or something
       else
         super
       end
     end
   end

I'm not very sure about the feature itself though. There are times
when you may want to eager load the joined table.

Thanks for the feedback, Pratik. That's actually where I plugged in to do it in the linked github repo, but I sort of piggybacked on joindependency a bit to do the heavy lifting.

I've got an alternate take on the concept up at
http://github.com/ernie/meta_where/tree/autojoin now.

I think I like this one better, and it seems to work OK with
eager_load and includes now, too. Activated by adding autojoin into
the method chain. See the gist at http://gist.github.com/376585 for
results.

There may still be some broken stuff or drawbacks, but I'm feeling
pretty good about it in general.

While working on this, I came upon what I believe is a bug in a
relatively unused part of the JoinDependency/eager_loading code
pertaining to find_with_associations, though I may be mistaken.

I've put up a lighthouse ticket at https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/4463
if anyone cares to confirm.

By way of update, the bug was confirmed and the patch is available at
https://rails.lighthouseapp.com/projects/8994/tickets/4463.