ActiveRecordのpluckメソッドでjoinsした先のカラムの値を取得したい

こんにちは!kossyです!




さて、今回はActiveRecordのpluckメソッドでjoinsした先のカラムの値を取得する方法について、ブログに残してみたいと思います。



環境

Ruby 2.6.8
Rails 6.0.4
MacOS catalina



前提

以下のテーブル構成があるとします。

class CreateCompanies < ActiveRecord::Migration[6.0]
  def change
    create_table :companies do |t|
      t.string :name, null: false

      t.timestamps
    end
  end
end
class CreatePositions < ActiveRecord::Migration[6.0]
  def change
    create_table :positions do |t|
      t.string :name, null: false
      t.references :company, null: false, foreign_key: true, index: true

      t.timestamps
    end
  end
end
class CreateDepartments < ActiveRecord::Migration[6.0]
  def change
    create_table :departments do |t|
      t.string :name, null: false
      t.string :ancestry
      t.integer :ancestry_depth
      t.references :company, null: false, foreign_key: true, index: true

      t.timestamps
    end
  end
end
class CreateEmployees < ActiveRecord::Migration[6.0]
  def change
    create_table :employees do |t|
      t.string :first_name, null: false
      t.string :last_name, null: false
      t.string :first_name_kana, null: false
      t.string :last_name_kana, null: false
      t.string :middle_name
      t.string :middle_name_kana
      t.boolean :sex, null: false
      t.date :hired_at, null: false
      t.date :retired_at
      t.references :company, null: false, foreign_key: true, index: true
      t.references :position, null: false, foreign_key: true, index: true
      t.references :department, null: false, foreign_key: true, index: true

      t.timestamps
    end
  end
end
class CreateOrders < ActiveRecord::Migration[6.0]
  def change
    create_table :orders do |t|
      t.string :customer_name, null: false
      t.integer :price, null: false
      t.integer :status, null: false
      t.date :ordered_at, null: false
      t.references :employee, null: false, foreign_key: true, index: true
      t.references :company, null: false, foreign_key: true, index: true

      t.timestamps
    end
  end
end
class Company < ApplicationRecord
  with_options dependent: :destroy do
    has_many :employees
    has_many :departments
    has_many :orders
    has_many :positions
  end
end
class Department < ApplicationRecord
  belongs_to :company
  has_many :employees
  has_ancestry cache_depth: true
end
class Employee < ApplicationRecord
  belongs_to :company
  belongs_to :department
  belongs_to :position
  has_many :orders

  enum sex: { male: false, female: true }
end
class Order < ApplicationRecord
  belongs_to :employee
  belongs_to :company

  enum status: [:un_official, :fixed]
end
class Position < ApplicationRecord
  belongs_to :company
  has_many :employees
end

pluckを使ってjoins先の値を取得

例えば、Employeeが所属する会社の名前を取得したいとします。

この場合、以下のように記述することで、目的の値を取得できます。

$ Employee.joins(:company).pluck('companies.name')

以下のようなjoins文を書いても、joins先のテーブルの値を取得することができます。

$ Company.joins(employees: :orders).distinct.pluck('orders.price')

勉強になりました。


大いに参考にさせていただいたサイト

素晴らしい記事の執筆誠にありがとうございます。

Railsアプリの処理を100倍以上に高速化して得られた知見 – PSYENCE:MEDIA