arel_tableを利用してexistsの外部副問い合わせを実現する
ActiveRecordで複雑なことをやろうとするとarel_tableだと伺いまして。
準備
rails -v Rails 4.1.0
ruby -v ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-darwin13.0]
rails new test_app cd test_app rails g model yamada name:string rails g model nanika status:string name:string yamada:references bundle exec rake db:migrate bundle exec rails console
まず、Arel::Tableオブジェクトを取得するところから。
nanika = Nanika.arel_table => #<Arel::Table...
今回はexistsの相関副問い合わせを作ってみました。
t1 = nanika.project(nanika[:yamada_id]).where(nanika[:status].eq('good')).group(nanika[:yamada_id]).as('t1') => #<Arel::Nodes... t1.to_sql => "(SELECT \"nanikas\".\"yamada_id\" FROM \"nanikas\" WHERE \"nanikas\".\"status\" = 'good' GROUP BY \"nanikas\".\"yamada_id\") t1"
yamada = Yamada.arel_table condition = yamada.from(t1).where(t1[:yamada_id].eq(yamada[:id])).project("'X'").exists Yamada.where(condition) Yamada Load (0.2ms) SELECT "yamadas".* FROM "yamadas" WHERE (EXISTS (SELECT 'X' FROM (SELECT "nanikas"."yamada_id" FROM "nanikas" WHERE "nanikas"."status" = 'good' GROUP BY "nanikas"."yamada_id") t1 WHERE t1."yamada_id" = "yamadas"."id")) => #<ActiveRecord::Relation []>
レコード入れてないのでやまだは見つかりませんでしたが、EXISTSで外側のテーブルを参照できています!!
関係無いのもあるけどarel_table調査のときの参考にしたページの断片