• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:rails 1:多で指定した子を持たない親の検索)

Railsで1対多の関連で指定した子を持たない親の検索方法

このQ&Aのポイント
  • Rails4で1対多関連のモデルに対して指定した子を持たない親の検索方法について教えてください。
  • 現在は除外する値を指定して親を検索するという方法で実装していますが、もっとスマートな方法があれば教えてください。
  • 子の条件を複数指定できるようにしたいです。

質問者が選んだベストアンサー

  • ベストアンサー
  • ki073
  • ベストアンサー率77% (491/634)
回答No.3

SQLで書くのなら、NOT EXISTSを使えば1つにできそうなのですが、  RailsのActiveRecordでは無理なようです。 Arelで可能なようですが、かなり分かりにくいコードになってしまうようです。 分かりやすさと速さから見て、No.2のコードが良さそうです。(ちゃんと動きますよね) 興味がありましたら、上のキーワードで検索してみてください。 ActiveRecordは検索結果をRuby変数に変換する時にでデータ量が多いと遅くなります。 今回の場合はデータ量が少ないと思いますので、速度にはあまり影響しないと思います。

dipperlight
質問者

お礼

NOT EXISTS、実際に使ったことが無いので存在をすっかり忘れていました…… Arelはor検索の際に少し検索したことがありますが 今回はそこまで速さの追及はしていないのでわかりやすさを重視してみます 補足説明までありがとうございました

その他の回答 (2)

  • ki073
  • ベストアンサー率77% (491/634)
回答No.2

ちょっと勘違いでした。一つのSQL発行で済ませたかったのですが、ActiveRecordですぐに思いついたのは excludes = [ '除外1', '除外2',... ] exclude_ids=Parent.joins(:children).where(children: {value: excludes}).uniq.pluck(:id) Parent.where.not(id: exclude_ids) excludes配列の要素数よりexclude_idsが同じか少なくなるので そんなに遅くはないとは思いますが もう少し考えてみますが

dipperlight
質問者

お礼

ありがとうございます すごくスマートなコードになりました SQL発行回数も大幅に減ったので処理が軽くなりました 「特定の子をもたない親」の検索を直接的に行うのはやはり難しいのでしょうか 全体から「特定の子をもつ親を除外」というのが、なんだかちょっと気持ち悪い感じがします # SQLでもどうかけばいいかよくわからない

  • ki073
  • ベストアンサー率77% (491/634)
回答No.1

以下でいけると思います excludes = [ '除外1', '除外2',... ] Parent.joins(:children).where.not(children: {value: excludes})

dipperlight
質問者

お礼

返答ありがとうございます 試してみたところ 親A:子[1,2,3] 親B:子[4,5,6] に対し、1を持たない、という条件で教えていただいた式を実行すると [A,A,B,B,B]が返ってきてしまいます もしかするとモデルの設計自体が悪いのでしょうか……