Have you ever needed to get the most recent post for each user in rails, but didn’t know how to do it without using map?
Or maybe something similar, like:
Here is an example of a simple way to do it when you can use the id
column to sort the records.
class Post < ActiveRecord::Base
belongs_to :user
scope :first_per_user, -> {
where(id: select("min(id)").group(:user_id))
}
scope :last_per_user, -> {
where(id: select("max(id)").group(:user_id))
}
end
puts Post.first_per_user
# => SELECT "posts".*
# FROM "posts"
# WHERE "posts"."id"
# IN (SELECT min(id) FROM "posts" GROUP BY "posts"."user_id")
puts Post.last_per_user
# => SELECT "posts".*
# FROM "posts"
# WHERE "posts"."id"
# IN (SELECT max(id) FROM "posts" GROUP BY "posts"."user_id")
But here you will find a repo, with:
user.last_post
or posts[user]
.You can find the repo in: bhserna/first_or_last_per_user.
The 5 methods are:
The 2 benchamarks are:
The 2 examples on how to associates the posts to the users are:
Install the dependencies with bundle install
.
Database setup - run the command:
ruby db/setup.rb
ruby examples/<file name>
. For example:ruby example/00_example.rb
db/seeds.rb
and re-run ruby db/setup.rb
to test different scenarios.This repo uses the Active Record Playground that you can also use to play with some Active Record models in isolation and without creating a full rails app.
This example is based on a proposal of Steave Polito, but trying to implement the samething with one query.
Making things work isn't enough for you any more? Now you need to consider performance and scalability?
... But you normally have troubles fixing n+1 queries and trying to find why active record is ignoring your "includes"?
Are you are worried because you feel unqualified to tackle tasks with complex data models?
Sign up to learn how to fix n+1 queries on Rails