Techioz Blog

結合されたRailsテーブルの列挙型を参照するクエリ

概要

私のドメイン モデルを簡略化した次の表現を考えてみましょう。

class Item < ApplicationRecord
  has_many :tags
end

class Tag < ApplicationRecord
  belongs_to :item
  enum :value, %i{hot cold}

  validates :value, uniqueness: { scope: :item_id }
end

すべてのアイテムには、プログラムに関連する可能性のあるアイテムのプロパティを示す 0 個以上のタグがあります。この例では、有効なタグは「hot」と「cold」のみです。

「ホット」とタグ付けされたすべてのアイテムを検索したい場合は、次のように書くことができます。

Item.joins(:tags).where('tags.value = 0')

当然のことながら、列挙型の整数値の代わりに「ホット」という単語を書きたいと思います。名前付き引数を使用して ActiveRecord の処理を強制することができます。

Item.joins(:tags).where('tags.value': 'hot')

しかし、名前が有効な Ruby 識別子ではない名前付き引数を持つのは、ある意味…間違っているように感じます。このような奇妙な疑似変数を使用せずに、このクエリを作成するもっと巧妙な方法はあるでしょうか?

解決策

これはもっと良い感じですか?

Item.joins(:tags).where(tags: {value: :hot})

または

class Item < ApplicationRecord
  has_many :tags

  scope :tagged, ->(value) { joins(:tags).where(tags: {value:}) }
end

Item.tagged(:hot)