Module: TypedEAV::HasTypedEAV

Extended by:
ActiveSupport::Concern
Defined in:
lib/typed_eav/has_typed_eav.rb

Overview

Include this in any ActiveRecord model to give it typed custom fields.

class Contact < ApplicationRecord
  has_typed_eav
end

class Contact < ApplicationRecord
  has_typed_eav scope_method: :tenant_id
end

This gives you:

# Reading/writing values
contact.typed_values                    # => collection
contact.initialize_typed_values         # => builds missing values with defaults
contact.typed_eav_attributes = [...]    # => bulk assign via nested attributes

# Querying (the good stuff)
Contact.where_typed_eav(
  { name: "age", op: :gt, value: 21 },
  { name: "status", op: :eq, value: "active" }
)

# Or the short form with a hash:
Contact.with_field("age", :gt, 21)
Contact.with_field("status", "active")  # :eq is default

Defined Under Namespace

Modules: ClassQueryMethods, InstanceMethods

Class Method Summary collapse

Class Method Details

.definitions_by_name(defs) ⇒ Object

Indexes field definitions by name with deterministic collision resolution: when a global (scope=NULL) and a scoped field share a name, the scoped row wins. ‘for_entity(name, scope:)` returns both rows on a collision, and a bare `index_by(&:name)` would let DB row order pick the winner. Shared by the class-query path (ClassQueryMethods#where_typed_eav) and the instance path (InstanceMethods#typed_eav_defs_by_name) so the two can’t drift.



41
42
43
# File 'lib/typed_eav/has_typed_eav.rb', line 41

def self.definitions_by_name(defs)
  defs.to_a.sort_by { |d| d.scope.nil? ? 0 : 1 }.index_by(&:name)
end

.definitions_multimap_by_name(defs) ⇒ Object

Indexes field definitions by name into a multi-map (one name →array of fields). Used by the class-query path under ‘TypedEAV.unscoped { }`, where the same field name may legitimately exist across multiple tenant partitions and we must OR-across all matching field_ids per filter rather than collapse to a single row.



50
51
52
# File 'lib/typed_eav/has_typed_eav.rb', line 50

def self.definitions_multimap_by_name(defs)
  defs.to_a.group_by(&:name)
end