Techioz Blog

RoR ActiveRecord スコープ + has_many をクエリする方法

概要

Ruby on Rails でよくある問題に直面しています。ネストされた has_many リレーションがあります アカウント > has_many > サイト > has_many > ページ > has_many > ブロック

class Site < ApplicationRecord
  belongs_to :account
  enum status: [:enabled, :disabled, :archived, :deleted]
end

class Account < ApplicationRecord
  has_many :sites
  enum status: [:enabled, :disabled, :archived, :deleted]
end

この例では、すべての有効なサイトをクエリするにはどうすればよいでしょうか? Site.enabled を実行してスコープを使用できます。 Account.enabled も使用できます。ただし、有効なスコープが active_relation を返すため、Account.enabled.sites は使用できません。 Railsでそれを実現するきれいな方法はありますか?

現在の回避策は Account.enabled.each(&:sites) ですが、これは active_relation ではなく配列になっています。そのため、Account.enabled.each(&:sites).enabled を実行しても、適切にフィルタリングされません。

Rails APIドキュメントを調べて、配列を返す代わりにactive_relationクラスを保持するそれぞれを検索します。

解決策

いいえ、あなたが望むことを行うための組み込みの方法はありません。これをサイト側で行うには、有効なアカウントが関連付けられているもののみを返すスコープをサイト内に作成します。

  scope :with_enabled_account, -> { joins(:account).merge Account.enabled }