Associationは書けないんだけどINNER JOINしたテーブルのカラムを参照したいんです
たぶんPrimaryKeyじゃないカラムで紐付けあっているテーブルだとbelongs_to
とかでAssociationを定義できない?気がしています。試していないんですけど。
そんなときに結合したテーブルのカラムを触りたい場合のやり方を2通り。
- ターゲットになるテーブルのActiveRecord::Relationを取得するメソッドを作る
- joins
は普通に書いて、selectに対象テーブル名付きでカラム名を指定するを書く(2013/10/13訂正 なんでこう書いたんや。。)
ターゲットになるテーブルのActiveRecord::Relationを取得するメソッドを作る
class Employee def job_history JobHistory.where(employee_id: employee_id) end end Employee.find(101).job_history.each do |r| puts r.inspect end # => #<JobHistory employee_id: 101, start_date: "1997-09-21 00:00:00", end_date: "2001-10-27 00:00:00", job_id: "AC_ACCOUNT", department_id: 110> # => #<JobHistory employee_id: 101, start_date: "2001-10-28 00:00:00", end_date: "2005-03-15 00:00:00", job_id: "AC_MGR", department_id: 110>
scopeにできればもっとすっきりしそうなものだけど……
joinsは普通に書いて、selectに対象テーブル名付きでカラム名を指定するを書く
joinsはもう少し簡単な書き方あります。。
emp = Employee.arel_table hist = JobHistory.arel_table join_str = emp.join(hist).on( emp[:employee_id].eq(hist[:employee_id]) ).join_sources Employee.select(hist[Arel.sql('*')]).joins(join_str).where(employee_id: 101).each do |r| puts "#{r.inspect} and JobHistory attributes<start_date: #{r.start_date}, end_date: #{r.end_date}>" end # => #<Employee employee_id: 101, job_id: "AC_ACCOUNT", department_id: 110> and JobHistory attributes<start_date: 1997-09-21 00:00:00 +0900, end_date: 2001-10-27 00:00:00 +0900> # => #<Employee employee_id: 101, job_id: "AC_MGR", department_id: 110> and JobHistory attributes<start_date: 2001-10-28 00:00:00 +0900, end_date: 2005-03-15 00:00:00 +0900>
joinした側のテーブルのカラムのアクセサをしれっと呼び出せばいける。
参考
メモ
ArelでOUTER JOINを書きたかったら多分emp.join(hist, Arel::Nodes::OuterJoin).on(略)
って書くのかなー。
参考:sql - ActiveRecord/ARel modify ON
in a left out join from includes - Stack Overflow