こういうsqlをActiveRecordを使って表現したい
SELECT * FROM posts INNER JOIN comments ON comments.post_id = posts.id WHERE comments.created_at >= '2019-01-01'
つまり、2019年以降にコメントがついたpostのデータを取得したい。
こう書いたらできた
Post.joins(:comments).where("comments.created_at >= ? ", Date.new(2019,1,1))
↓実行されたsql
SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" WHERE (comments.created_at >= '2019-01-01' ) LIMIT $1 [["LIMIT", 11]]
scopeを使うともう少しいい感じになった。
Commentモデルに2019年以降のデータを取得する条件をscopeで定義する
comment.rb
class Comment < ApplicationRecord belongs_to :post scope :recent, -> { where(arel_table[:created_at].gteq Date.new(2019,1,1))} end # gt は > を意味する。 # gteq は >= # lt は < # lteq は <=
この状態で以下の様に書く
Post.joins(:comments).merge(Comment.recent)
↓実行されたsql
SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" WHERE "comments"."created_at" >= '2019-01-01' LIMIT $1 [["LIMIT", 11]]
◆その他
なんとなく文字列でなくシンボルなどでうまく書きたい気がしてしまうが、
普通に文字列でwhere("comments.created_at >= ? ", Date.new(2019,1,1)
とか書くほうが可読性が良さそうと思ってしまう。どうなんだろうか。。