Hacker News new | ask | show | jobs
by blueplanet200 2458 days ago
It's more composable with multiple includes.

For instance, if you have a simple active record type:

class User has_many :comments; has_many :likes; end

User.includes(:comments, :likes).find(user_id)

Generates 3 queries, but importantly the number of records returned is appropriate.

User.joins(:comments, :likes).where(users: { id: user_id })

Generates only a single query, but the number of records returned from this join is the product of comments*likes for this particular user.

I find the includes stuff easier to reason about as the amount of associations you need loaded in memory becomes more complex.

2 comments

Hm, I see now where we're talking past each other - I was thinking more along the lines of "user has orders has order lines has products has prices" (where you might traditionally make a (hierarchy of) database view(s)).

Not "user has orders", and also "user has favorite products".

So the problem is active record is no good at joins?

(That is, it's hard/impossible via the active record DSL to make the correct nested join?)

By the way (you may know this) when staying within active record convention, you should never need to single out the ".id" and ".foreign_model_id" fields:

User.joins(:comments, :likes).where(user: some_user)

(where some_user is an instance of User).

I'm still not quite comfortable enough with AR, but I think, leaning on this: https://www.learneroo.com/modules/137/nodes/768

I think what you want in your second case is simply?:

User.joins(:comments, :likes).where(user: some_user).uniq

(I'd have to create some models and watch what ".to_sql" creates to be certain, though)

> So the problem is active record is no good at joins?

You encounter this problem whether you use an ORM or not.