active_record 関連テーブルを条件にして検索をする
Date:2016-04-28 16:24:32 +0900
Categories: ETC
Categories: ETC
やっぱりよくわかっていなかったので、メモ。
要は joinsしたテーブルを検索状態にしたいのだけど…というやつです。
目的
Record は Category に紐付いていて、recordの検索の条件に categoryの中にあるカラムを使いたくなりました。
activerecordだけで調べてピンとこなかったので、ここぞとばかりにsqlから学び直すことに。
目的を達成しそうなsql
SELECT "records".*, "categories"."is_payment" FROM "records" INNER JOIN "categories" ON "records"."category_id" = "categories"."id" WHERE "categories"."is_payment" = false;
するとこんな感じの返しがきた。
id | money | date | card | memo | created_at | updated_at | category_id | user_id | is_payment ----+--------+------------+------+------+----------------------------+----------------------------+-------------+---------+------------ 41 | 290000 | 2016-04-10 | f | | 2016-04-27 09:52:07.124605 | 2016-04-27 09:52:07.124605 | 21 | 1 | f (1 row)
これをactive recordに変換する
まずjoinsから確認してみた。.to_sqlメソッドを使うと発行されるsqlを見ることができるので便利だった。
$ puts Record.all.joins(:category).to_sql SELECT "records".* FROM "records" INNER JOIN "categories" ON "categories"."id" = "records"."category_id" => nil
意外と発行してもらいたいことと近そうだ。これにwhereをつけていい感じにはきだしてくれたぽい。
$ puts Record.all.joins(:category).where("categories.is_payment = ?", false).to_sql SELECT "records".* FROM "records" INNER JOIN "categories" ON "categories"."id" = "records"."category_id" WHERE (categories.is_payment = 'f')
結果は
Record.all.joins(:category).where("categories.is_payment = ?", false) Record Load (0.5ms) SELECT "records".* FROM "records" INNER JOIN "categories" ON "categories"."id" = "records"."category_id" WHERE (categories.is_payment = 'f') => [#<Record:0x007fdbbf55a2b0 id: 41, money: 290000, date: Thu, 28 Apr 2016, card: false, memo: "", created_at: Thu, 28 Apr 2016 07:02:28 UTC +00:00, updated_at: Thu, 28 Apr 2016 07:02:28 UTC +00:00, category_id: 21, user_id: 1>]
で無事に取れた様子。
where(“categories.is_payment = ?”, false) この部分を文字列じゃない形で渡してあげたい。
追記: 2016/04/28 16:29
と思って調べてみたら、やっぱりあった。
Record.all.joins(:category).where(categories: { is_payment: false} ) という書き方で同等になる模様。
sql書かないと覚えなさそうなので、こんな感じでいろいろ遊んで覚えていきたい。
Tweet