brianhempel / active_record_union

UNIONs in ActiveRecord! Adds proper union and union_all methods to ActiveRecord::Relation.
Other
423 stars 41 forks source link

Separate the table name from the table subquery #1

Closed Mackaber closed 8 years ago

Mackaber commented 9 years ago

Hello, I noticed that when you use .union, it automatically names the subquery as the table name, however this sometimes is not what you want, specifically when you have an aggregate function like SUM, and you need to refer to the original table that its name has already used by the subquery.

So I wrote a little workaround for this, you can check it here.

I'm still not sure that's the best way to implement it, that's why I didn't ask for a pull request, but either way, I wanted you to consider it.

brianhempel commented 9 years ago

From the example in your README:

current_user.posts.union(Post.published,true)
SELECT "posts".* FROM (
  SELECT "posts".* FROM "posts"  WHERE "posts"."user_id" = ?
  UNION
  SELECT "posts".* FROM "posts"  WHERE (published_at < '2014-07-19 16:04:21.918366')
) posts_union, posts

…you are selecting "posts".* from posts_union, posts, which if loaded into ActiveRecord would actually load every single post, not the union result. You would want to SELECT "posts_union".* to load the records from the union. However, if you SELECT "posts_union".*, then any .where() calls will filter "posts", which we don't want.

current_user.posts.union(Post.published,true).where(public: true)
SELECT "posts_union".* FROM (
  SELECT "posts".* FROM "posts"  WHERE "posts"."user_id" = ?
  UNION
  SELECT "posts".* FROM "posts"  WHERE (published_at < '2014-07-19 16:04:21.918366')
) posts_union, posts WHERE "posts"."public" = 't'

…we'd probably want WHERE "posts_union"."public" = 't' instead of WHERE "posts"."public" = 't'.

Maybe something like SELECT "posts".* FROM posts AS original_posts, (union stuff) posts

In any case, the whole thing is a CROSS JOIN which weirds me out. Why do you need a CROSS JOIN?

I'm not sure this is a problem that ActiveRecordUnion should support. Can you provide a full example of what kind of aggregation you are trying to do?