Class: ROM::Relation
- Inherits:
-
Object
- Object
- ROM::Relation
- Extended by:
- Dry::Core::ClassAttributes, ClassInterface
- Includes:
- Commands, Materializable
- Defined in:
- core/lib/rom/relation.rb,
core/lib/rom/relation/name.rb,
core/lib/rom/relation/wrap.rb,
core/lib/rom/relation/graph.rb,
core/lib/rom/relation/loaded.rb,
core/lib/rom/relation/curried.rb,
core/lib/rom/relation/combined.rb,
core/lib/rom/relation/commands.rb,
core/lib/rom/relation/view_dsl.rb,
core/lib/rom/relation/composite.rb,
core/lib/rom/relation/materializable.rb,
core/lib/rom/relation/class_interface.rb
Overview
Base relation class
Relation is a proxy for the dataset object provided by the gateway. It can forward methods to the dataset, which is why the "native" interface of the underlying gateway is available in the relation
Individual adapters sets up their relation classes and provide different APIs depending on their persistence backend.
Direct Known Subclasses
Defined Under Namespace
Modules: ClassInterface, Commands, Materializable Classes: Combined, Composite, Curried, Graph, Loaded, ViewDSL, Wrap
Constant Summary collapse
- NOOP_OUTPUT_SCHEMA =
Default no-op output schema which is called in
Relation#each
-> tuple { tuple }.freeze
Instance Attribute Summary collapse
-
#dataset ⇒ Object
readonly
Dataset used by the relation provided by relation's gateway.
-
#mappers ⇒ MapperRegistry
readonly
An optional mapper registry (empty by default).
-
#name ⇒ Object
readonly
The relation name.
- #relation_name ⇒ Object included from ClassInterface readonly
-
#schema ⇒ Schema
readonly
Relation schema, defaults to class-level canonical schema (if it was defined) and sets an empty one as the fallback.
-
#struct_namespace(ns) ⇒ Relation
readonly
Return a new relation configured with the provided struct namespace.
Class Method Summary collapse
-
.[](adapter) ⇒ Class
extended
from ClassInterface
Return adapter-specific relation subclass.
-
.auto_map ⇒ Object
Whether or not a relation and its compositions should be auto-mapped.
-
.auto_struct ⇒ Object
Whether or not tuples should be auto-mapped to structs.
-
.dataset(&block) ⇒ Object
extended
from ClassInterface
Set or get custom dataset block.
-
.forward(*methods) ⇒ Object
extended
from ClassInterface
Dynamically define a method that will forward to the dataset and wrap response in the relation itself.
-
.gateway ⇒ Object
Manage the gateway.
-
.schema(dataset = nil, as: nil, infer: false, &block) ⇒ Schema
extended
from ClassInterface
Specify canonical schema for a relation.
-
.struct_namespace ⇒ Object
Get or set a namespace for auto-generated struct classes.
-
.use(plugin, **options) ⇒ Object
extended
from ClassInterface
Include a registered plugin in this relation class.
-
.view(*args, &block) ⇒ Symbol
extended
from ClassInterface
Define a relation view with a specific schema.
Instance Method Summary collapse
-
#[](name) ⇒ Attribute
Return schema attribute.
-
#as(aliaz) ⇒ Relation
Return a new relation with an aliased name.
-
#associations ⇒ AssociationSet
Return schema's association set (empty by default).
-
#call ⇒ Relation::Loaded
Loads a relation.
-
#combine(*args) ⇒ Relation
Combine with other relations using configured associations.
-
#combine_with(*others) ⇒ Relation::Graph
Composes with other relations.
-
#command(type, mapper: nil, use: EMPTY_ARRAY, plugins_options: EMPTY_HASH, **opts) ⇒ ROM::Command
included
from Commands
Return a command for the relation.
-
#each {|Hash| ... } ⇒ Enumerator
Yields relation tuples.
-
#eager_load(assoc) ⇒ Relation
Return a graph node prepared by the given association.
-
#first ⇒ Object
included
from Materializable
Return first tuple from a relation coerced to an array.
-
#map_to(klass, **opts) ⇒ Relation
Return a new relation that will map its tuples to instances of the provided class.
-
#map_with(*names, **opts) ⇒ Relation::Composite
Maps relation with custom mappers available in the registry.
-
#new(dataset, **new_opts) ⇒ Object
Return a new relation with provided dataset and additional options.
-
#node(name) ⇒ Relation
Create a graph node for a given association identifier.
-
#one ⇒ Object
included
from Materializable
Delegate to loaded relation and return one object.
-
#one! ⇒ Object
included
from Materializable
Delegate to loaded relation and return one object.
-
#schemas ⇒ Hash<Symbol=>Schema>
Return all registered relation schemas.
-
#to_a ⇒ Array<Hash>
Materializes a relation into an array.
-
#to_ast ⇒ Array
Returns AST for the wrapped relation.
-
#with(opts) ⇒ Relation
Returns a new instance with the same dataset but new options.
-
#wrap(*names) ⇒ Wrap
Wrap other relations using association names.
-
#wrap_around(*others) ⇒ Relation::Wrap
Wrap around other relations.
Instance Attribute Details
#dataset ⇒ Object (readonly)
Returns dataset used by the relation provided by relation's gateway.
137 |
# File 'core/lib/rom/relation.rb', line 137 param :dataset |
#mappers ⇒ MapperRegistry (readonly)
Returns an optional mapper registry (empty by default).
180 |
# File 'core/lib/rom/relation.rb', line 180 option :mappers, default: -> { self.class.mapper_registry } |
#name ⇒ Object (readonly)
Returns The relation name.
149 |
# File 'core/lib/rom/relation.rb', line 149 option :name, default: -> { self.class.schema ? self.class.schema.name : self.class.default_name } |
#relation_name ⇒ Object (readonly) Originally defined in module ClassInterface
#schema ⇒ Schema (readonly)
Returns relation schema, defaults to class-level canonical schema (if it was defined) and sets an empty one as the fallback.
144 |
# File 'core/lib/rom/relation.rb', line 144 option :schema, default: -> { self.class.schema || self.class.default_schema } |
#struct_namespace(ns) ⇒ Relation (readonly)
Return a new relation configured with the provided struct namespace
176 |
# File 'core/lib/rom/relation.rb', line 176 option :struct_namespace, reader: false, default: -> { self.class.struct_namespace } |
Class Method Details
.[](adapter) ⇒ Class Originally defined in module ClassInterface
Return adapter-specific relation subclass
.auto_map ⇒ Boolean .auto_map(value) ⇒ Object
Whether or not a relation and its compositions should be auto-mapped
84 |
# File 'core/lib/rom/relation.rb', line 84 defines :auto_map |
.auto_struct ⇒ Boolean .auto_struct(value) ⇒ Object
Whether or not tuples should be auto-mapped to structs
95 |
# File 'core/lib/rom/relation.rb', line 95 defines :auto_struct |
.dataset(&block) ⇒ Object Originally defined in module ClassInterface
Set or get custom dataset block
This block will be evaluated when a relation is instantiated and registered in a relation registry.
.forward(*methods) ⇒ Object Originally defined in module ClassInterface
Dynamically define a method that will forward to the dataset and wrap response in the relation itself
.gateway ⇒ Symbol .gateway(gateway_key) ⇒ Object
Manage the gateway
73 |
# File 'core/lib/rom/relation.rb', line 73 defines :gateway |
.schema(dataset = nil, as: nil, infer: false, &block) ⇒ Schema Originally defined in module ClassInterface
Specify canonical schema for a relation
With a schema defined commands will set up a type-safe input handler automatically
.struct_namespace ⇒ Module .struct_namespace(namespace) ⇒ Object
Get or set a namespace for auto-generated struct classes. By default, new struct classes are created within ROM::Struct
@example using custom namespace class Users < ROM::Relation[:sql] struct_namespace Entities end
users.by_pk(1).one! # => #
114 |
# File 'core/lib/rom/relation.rb', line 114 defines :struct_namespace |
.use(plugin, **options) ⇒ Object Originally defined in module ClassInterface
Include a registered plugin in this relation class
#view(name, schema, &block) ⇒ Symbol #view(name, &block) ⇒ Symbol Originally defined in module ClassInterface
Define a relation view with a specific schema
This method should only be used in cases where a given adapter doesn't support automatic schema projection at run-time.
It's not needed in rom-sql
Instance Method Details
#[](name) ⇒ Attribute
Return schema attribute
206 207 208 |
# File 'core/lib/rom/relation.rb', line 206 def [](name) schema[name] end |
#as(aliaz) ⇒ Relation
Return a new relation with an aliased name
555 556 557 |
# File 'core/lib/rom/relation.rb', line 555 def as(aliaz) with(name: name.as(aliaz)) end |
#associations ⇒ AssociationSet
Return schema's association set (empty by default)
461 462 463 |
# File 'core/lib/rom/relation.rb', line 461 def associations schema.associations end |
#call ⇒ Relation::Loaded
Loads a relation
353 354 355 |
# File 'core/lib/rom/relation.rb', line 353 def call Loaded.new(self) end |
#combine(*associations) ⇒ Relation #combine(*associations, **nested_associations) ⇒ Relation #combine(associations) ⇒ Relation
Combine with other relations using configured associations
253 254 255 |
# File 'core/lib/rom/relation.rb', line 253 def combine(*args) combine_with(*nodes(*args)) end |
#combine_with(*others) ⇒ Relation::Graph
Composes with other relations
264 265 266 |
# File 'core/lib/rom/relation.rb', line 264 def combine_with(*others) Combined.new(self, others) end |
#command(type, mapper: nil, use: EMPTY_ARRAY, plugins_options: EMPTY_HASH, **opts) ⇒ ROM::Command Originally defined in module Commands
Return a command for the relation
This method can either return an existing custom command identified
by type
param, or generate a command dynamically based on relation
AST.
#each {|Hash| ... } ⇒ Enumerator
Yields relation tuples
Every tuple is processed through Relation#output_schema, it's a no-op by default
219 220 221 222 223 224 225 226 227 |
# File 'core/lib/rom/relation.rb', line 219 def each return to_enum unless block_given? if auto_map? mapper.(dataset.map { |tuple| output_schema[tuple] }).each { |struct| yield(struct) } else dataset.each { |tuple| yield(output_schema[tuple]) } end end |
#eager_load(assoc) ⇒ Relation
Return a graph node prepared by the given association
302 303 304 305 306 307 308 309 310 |
# File 'core/lib/rom/relation.rb', line 302 def eager_load(assoc) relation = assoc.prepare(self) if assoc.override? relation.(assoc) else relation.preload_assoc(assoc) end end |
#first ⇒ Object Originally defined in module Materializable
Return first tuple from a relation coerced to an array
#map_to(klass, **opts) ⇒ Relation
Return a new relation that will map its tuples to instances of the provided class
541 542 543 |
# File 'core/lib/rom/relation.rb', line 541 def map_to(klass, **opts) with(opts.merge(auto_map: false, auto_struct: true, meta: { model: klass })) end |
#map_with(*mappers) ⇒ Relation::Composite #map_with(*mappers, auto_map: true) ⇒ Relation::Composite
Maps relation with custom mappers available in the registry
When auto_map
is enabled, your mappers will be applied after performing
default auto-mapping. This means that you can compose complex relations
and have them auto-mapped, and use much simpler custom mappers to adjust
resulting data according to your requirements.
527 528 529 |
# File 'core/lib/rom/relation.rb', line 527 def map_with(*names, **opts) super(*names).with(opts) end |
#new(dataset, **new_opts) ⇒ Object
Return a new relation with provided dataset and additional options
Use this method whenever you need to use dataset API to get a new dataset and you want to return a relation back. Typically relation API should be enough though. If you find yourself using this method, it might be worth to consider reporting an issue that some dataset functionality is not available through relation API.
420 421 422 423 424 425 426 427 428 429 430 431 |
# File 'core/lib/rom/relation.rb', line 420 def new(dataset, **new_opts) opts = if new_opts.empty? elsif new_opts.key?(:schema) .merge(new_opts).reject { |k, _| k == :input_schema || k == :output_schema } else .merge(new_opts) end self.class.new(dataset, **opts) end |
#node(name) ⇒ Relation
Create a graph node for a given association identifier
289 290 291 292 293 |
# File 'core/lib/rom/relation.rb', line 289 def node(name) assoc = associations[name] other = assoc.node other.eager_load(assoc) end |
#one ⇒ Object Originally defined in module Materializable
Delegate to loaded relation and return one object
#one! ⇒ Object Originally defined in module Materializable
Delegate to loaded relation and return one object
#schemas ⇒ Hash<Symbol=>Schema>
Return all registered relation schemas
This holds all schemas defined via view
DSL
582 583 584 |
# File 'core/lib/rom/relation.rb', line 582 def schemas self.class.schemas end |
#to_a ⇒ Array<Hash>
Materializes a relation into an array
362 363 364 |
# File 'core/lib/rom/relation.rb', line 362 def to_a to_enum.to_a end |
#to_ast ⇒ Array
Returns AST for the wrapped relation
470 471 472 |
# File 'core/lib/rom/relation.rb', line 470 def to_ast [:relation, [name.relation, attr_ast, ]] end |
#with(opts) ⇒ Relation
Returns a new instance with the same dataset but new options
445 446 447 448 449 450 451 452 453 454 |
# File 'core/lib/rom/relation.rb', line 445 def with(opts) = if opts.key?(:meta) opts.merge(meta: .merge(opts[:meta])) else opts end new(dataset, **, **) end |
#wrap(*names) ⇒ Wrap
Wrap other relations using association names
333 334 335 |
# File 'core/lib/rom/relation.rb', line 333 def wrap(*names) wrap_around(*names.map { |n| associations[n].wrap }) end |
#wrap_around(*others) ⇒ Relation::Wrap
Wrap around other relations
344 345 346 |
# File 'core/lib/rom/relation.rb', line 344 def wrap_around(*others) wrap_class.new(self, others) end |