LoginSignup
5
1

More than 3 years have passed since last update.

[rails] 孫要素のカウント数(条件)で子要素の値を返す方法

Last updated at Posted at 2019-08-22

孫要素の条件で子要素の値を返す

はじめに

孫要素をincludes


Prefecture.includes(localities: :sub_locality)

子モデルをキャッシュ&絞込


Prefecture.includes(:localities).references(:localities).where("localities.name = ?", '東京都')

子モデル・孫モデルが存在するレコード抽出


Prefecture.joins(:localities).where("localities.name = ?", '新宿区')
Prefecture.joins(localities: :sub_localities).where("sub_localities.name = ?", '西新宿')

ここまでは、いろいろな記事でもっとわかりやすく書いてるものを参考にしてください。

本題

ここからが本題です!
今回ワタシが苦戦した内容が、「孫要素が必要な条件揃っていたら、子要素の値を返す」というものでした。

上記の例をつくるとすると、
1つの prefecture の 紐づく locality に、さらに紐づく sub_locality が100以上ある場合のみ値を返すコードを作りたい

試行段階


Prefecture.first.localities.joins(:sub_localities).group(:id).having('count_id >= 100').count(:id)
=> {2=>131, 3=>116, 11=>167, 13=>334, 15=>172, 16=>144, 17=>164, 19=>180, 24=>113, 38=>109, 186=>143}

こんな感じの結果が返ってくる。
locality.id をとれたので、成功!?

しかし、これで locality を絞るには、


locality_ids = Prefecture.first.localities.joins(:sub_localities).group(:id).having('count_id >= 100').count(:id).keys

のようにして、locality.id をとってきてから、


Locality.where(id: locality_ids)

と書かないといけない!めんどくさい

結果

一回で絞り込めないかな〜〜と検索してたらドンピシャのサイトがありました。
http://akinov.hatenablog.com/entry/2017/05/13/163911


Prefecture.first.localities.joins(:sub_localities).group(:id).having("count('*') >= ?", 100)
=> #<ActiveRecord::AssociationRelation [#<Locality id: 11, prefecture_id: 1, name: "~~~" ]>

としっかり locality のデータが返ってきました。

having("count('*') >= ?", 100)

こんな書き方でいけちゃうみたいです!
'*' ここは名前?みたいな感じなのでなんでも良き。(なはず)


Prefecture.first.localities.joins(:sub_localities).group(:id).having("count('*') >= ?", 100).count
=> {2=>131, 3=>116, 11=>167, 13=>334, 15=>172, 16=>144, 17=>164, 19=>180, 24=>113, 38=>109, 186=>143}

ちなみに、count つけるとこんな感じでデータが帰ってきます。

まとめ

  • google様での検索ワードってホント大事。
  • これが完全正解とは、限らないのでもっといい方法をご存じの方はご教授願います。
5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1