Create a gist now

Instantly share code, notes, and snippets.

@tai2 /a.rb
Created Sep 21, 2016

ActiveRecordで未公開の記事を含むカテゴリを抽出する
class Category < ActiveRecord:Base
has_many :posts
...
end
# publised :boolean
class Post < ActiveRecord:Base
...
end
Category
.left_outer_joins(:posts)
.group('categories.id')
.having('SUM(CASE WHEN NOT posts.published THEN 1 ELSE 0 END) > 0')
@f96q
f96q commented Sep 21, 2016

これでできるかと。

Category.includes(:posts).where(posts: {published: false})
@tai2
Owner
tai2 commented Sep 21, 2016 edited

あ…例が悪かった。

Category
.left_outer_joins(:posts)
.group('categories.id')
.having('SUM(CASE WHEN NOT posts.published THEN 1 ELSE 0 END) = 0')
# 最後 = 0 になってる点が違う

もやりたいのです(というか、どちらかというとこっち)。つまり、逆の全記事が公開されてるカテゴリ一覧。
(ちなみに、この例自体は実際のでなく、同等のSQLを架空の例で書いた)

たしかに、上の例は、ご指摘の書き方のがシンプル(なのでプロダクトに採用させてもらいました)。

@tai2
Owner
tai2 commented Sep 21, 2016

includesは、配列で言うとこのanyみたいなもんだと思うので、allに相等するやつがあればいいんだけど…。

@yatmsu
yatmsu commented Sep 21, 2016

outer join決め打ちならeager_load(:posts)でもよいね。

@tai2
Owner
tai2 commented Sep 21, 2016

http://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-eager_load
おお、よくわかってないけど、left joinを短かく書けるようなやつか

@f96q
f96q commented Sep 21, 2016

なるほど、全記事が公開されてるカテゴリ一覧だと、各カテゴリごとの件数出して
各カテゴリごとにそれぞれ全部publishedになってるか、みないとできないので
なかなか綺麗にいかないですね。

@yatmsu
yatmsu commented Sep 21, 2016

http://qiita.com/k0kubun/items/80c5a5494f53bb88dc58
これよくまとまってます。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment