Reputation: 674
Let's say, I have 2 different models; User, and Post. I want to get the latest post of every each user. So the output will be something like this.
[<Post user_id:1, content:"yadayada" ....>, <Post user_id:2, content:"blabla"...> ......]
No more than one record for each user is the part where i got little confused.
i googled this little bit and found complex active record queries to handle this. I am wondering if there is any way to this in simple rails3.present? ? "rails3" : "rails"
way.
It feels like this should not take more than 1 line code. Thanks in advance.
Upvotes: 2
Views: 1558
Reputation: 6310
Seeing as I cannot yet post comments, here is the answer to eager loading:
The N+1 problem means that ActiveRecord will not get the posts, when you query for all your users using User.all
, therefore ActiveRecord will fire a new SQL query that selects the last post for every single user you iterate over. If you have 50 users, that will be one query for the fifty users and then fifty queries for each last post.
In case you have many users, the latency between the database and the Rails application will slow down the performance of the site and make users wait.
Eager loading allows you to fetch associated models to the model you are querying, so you can write:
User.includes(:posts).all.map { |u| u.posts.last }
ActiveRecord will first query for all the users, then query for all posts associated with all the users at once before iterating over the users, thereby avoiding doing a new query for each user. This is only two queries.
However, this also has it's drawbacks if your users have tons of posts, because you'll be fetching ALL posts of ALL users and not just the latest posts, thereby straining the database and generating a lot of undesired I/O.
Upvotes: 3