ActiveRecord Scoped Association
RailsのActiveRecordで条件付きのJOINを行いたいときに使える機能
条件付きeager_load
以下のような記述の場合、WHEREに条件がいく
code:ruby
class Author
has_many :articles
end
class Article
belongs_to :author
end
Author.eager_load(:published_articles).where(article: { published: true })
code:sql
SELECT *
FROM
"authors"
LEFT OUTER JOIN "articles"
ON "articles"."author_id" = "authors"."id"
WHERE
"articles"."published" = true
SQLでWHEREではなくJOINに条件を書きたいとき、associationの宣言時、第2引数にscopeを定義する
eager_load, joinsなどによるJOINでscopeに定義した条件を適用してくれる
code:ruby
class Author
has_many :published_articles, -> { where(published: true) }
end
Author.eager_load(:published_articles)
code:sql
SELECT *
FROM
"authors"
LEFT OUTER JOIN "articles"
ON "articles"."author_id" = "authors"."id"
AND "articles"."published" = true
API doc: https://api.rubyonrails.org/v6.1.4/classes/ActiveRecord/Associations/ClassMethods.html#method-i-belongs_to-label-Scopes
https://sharpknock.com/posts/programming/scoped-association.html
https://revs.runtime-revolution.com/conditional-eager-loading-in-rails-9b1c1c592897
How to Preload Rails Scopes
table同士の関係が1:Nであってもhas_oneとScoped Associationによって1:1であるかのように扱うこともできる
これはscoped associationを使わずとも実現できるが、使うと便利
code:ruby
class Author
has_one :latest_article, -> { where(latest: true) }
end
authors = Author.eager_load(:latest_article)
author.latest_article
# => arrayではなくArticleのインスタンスが得られる