📚

Railsの親子モデルで、子レコードが存在しない親レコードを取得する方法

2023/03/12に公開

概要

Railsの親子モデルで、子レコードが存在しない親レコードを取得する方法を記載する。

検証コード

# frozen_string_literal: true

require 'bundler/inline'

gemfile(true) do
  gem 'activerecord', '7.0.4'
  gem 'sqlite3'
end

require 'active_record'
require 'minitest/autorun'
require 'logger'

ActiveRecord::Base.establish_connection(adapter: :sqlite3, database: ':memory:')
ActiveRecord::Base.logger = Logger.new($stdout)

ActiveRecord::Schema.define do
  create_table :books, force: true do |t|
    t.string :name
  end

  create_table :chapters, force: true do |t|
    t.references :book
    t.string :name
  end
end

class Book < ActiveRecord::Base
  has_many :chapters
end

class Chapter < ActiveRecord::Base
  belongs_to :book
end

class Muroto < Minitest::Test
  def test_muroto
    yomichi = Book.new(name: '夜道')
    yomichi.chapters.new(name: '尾道')
    yomichi.save!

    ax = Book.create!(name: 'AX')

    assert_equal Book.left_outer_joins(:chapters).where(chapters: { id: nil }), [ax]
    assert_equal Book.where.missing(:chapters), [ax]
  end
end

説明

LEFT OUTER JOINをおこない、子モデルのidnilのレコードで絞り込みました。missingメソッドでも同様のクエリが発行されます。

Discussion