やる気がストロングZERO

やる気のストロングスタイル

【ActiveRecord】テーブルをまたいでwhere句条件を書きたい時

こういうsqlActiveRecordを使って表現したい

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)とか書くほうが可読性が良さそうと思ってしまう。どうなんだろうか。。