Class: TypedEAV::BulkRead
- Inherits:
-
Object
- Object
- TypedEAV::BulkRead
- Defined in:
- lib/typed_eav/bulk_read.rb
Overview
Bulk-read query object. Returns { record_id => { field_name => value } }
for an Enumerable of host records — the class-method bulk variant of
HasTypedEAV::InstanceMethods#typed_eav_hash. N+1-free regardless of
record count or field count.
fields: is an optional projection of field names. A nil selection keeps
the all-fields behavior; a non-nil selection is normalized to unique
strings, and only the selected winning definitions' values are loaded.
Unknown names are ignored, as are names that are not defined for a
particular record's partition tuple. An empty selection returns one empty
inner hash per record without querying definitions or values.
source: :database (the default) always reads a fresh Value graph. The
explicit source: :preloaded mode projects only the already-loaded
typed_values targets and their loaded field associations; it never
falls back to an association query. Incomplete preload requirements raise
ArgumentError before projection. The preloaded mode is therefore a
snapshot of caller-owned in-memory records and can include unsaved Value
assignments; it never saves or mutates those records.
Pipeline
1. validate_records!
Query bound
Database mode performs up to three SELECTs — one bulk Value query, one
field-association query for those values, and one definition query for the
union of requested partitions. The preloaded mode performs one fresh
definition SELECT and reads Value/field association targets in memory;
fields: [] bypasses even that definition query. Both bounds are
independent of record count and partition cardinality.
Single-class invariant
The polymorphic value query targets the host's canonical Rails
polymorphic_name, so an STI subclass reads rows stored for its base
class. Mixed, unrelated input would still be invalid; STI subclasses pass
via records.all?(host_class).
Instance Method Summary collapse
-
#initialize(host_class:, records:, fields: nil, source: :database) ⇒ BulkRead
constructor
A new instance of BulkRead.
- #to_hash ⇒ Object
Constructor Details
#initialize(host_class:, records:, fields: nil, source: :database) ⇒ BulkRead
Returns a new instance of BulkRead.
53 54 55 56 57 58 |
# File 'lib/typed_eav/bulk_read.rb', line 53 def initialize(host_class:, records:, fields: nil, source: :database) @host_class = host_class @records = records @fields = fields @source = source end |
Instance Method Details
#to_hash ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/typed_eav/bulk_read.rb', line 60 def to_hash validate_source! records = coerce_records return {} if records.empty? validate_record_classes!(records) selected_names = normalize_fields return empty_results(records) if selected_names == [] tuples_by_record = group_by_tuple(records) winning_ids_by_tuple = winning_ids_by_tuple(tuples_by_record.values.uniq, selected_names) values_by_record_id = if @source == :preloaded preloaded_values(records, tuples_by_record, winning_ids_by_tuple, selected_names) else preload_values(records, winning_ids_by_tuple, selected_names) end build_result(records, tuples_by_record, winning_ids_by_tuple, values_by_record_id, selected_names) end |