Search code examples
ruby-on-railsrubyjoinrails-activerecord

Query that references enum in joined Rails table


Consider the following simplified representation of my domain model.

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

Every item has zero or more tags which indicate properties of the item that may be relevant to my program. In this example, "hot" and "cold" are the only valid tags.

If I want to find all of the items which are tagged as "hot", I can write

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

Naturally, I'd prefer to write the word "hot" instead of the enum's integer value. I can sort of force ActiveRecord's hand with a named argument.

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

But having a named argument whose name is not a valid Ruby identifier feels sort of... wrong. Is there a neater way to make this query, that doesn't involve such a bizarre pseudo-variable?


Solution

  • Does this feel better:

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

    or

    class Item < ApplicationRecord
      has_many :tags
    
      scope :tagged, ->(value) { joins(:tags).where(tags: {value:}) }
    end
    
    Item.tagged(:hot)