Class: ROM::Repository::RelationProxy
- Inherits:
-
Object
- Object
- ROM::Repository::RelationProxy
- Extended by:
- Initializer
- Defined in:
- lib/rom/repository/relation_proxy.rb,
lib/rom/repository/relation_proxy/wrap.rb,
lib/rom/repository/relation_proxy/combine.rb
Overview
RelationProxy decorates a relation and automatically generates mappers that will map raw tuples into rom structs
Relation proxies are being registered within repositories so typically there’s no need to instantiate them manually.
Defined Under Namespace
Constant Summary collapse
- RelationRegistryType =
Types.Definition(RelationRegistry).constrained(type: RelationRegistry)
Instance Attribute Summary collapse
-
#relation ⇒ Relation, ...
readonly
The decorated relation object.
Instance Method Summary collapse
-
#adapter ⇒ Symbol
private
The wrapped relation’s adapter identifier ie :sql or :http.
-
#call(*args) ⇒ Object
Materializes wrapped relation and sends it through a mapper.
-
#combine(*args) ⇒ RelationProxy
included
from Combine
Combine with other relations.
-
#combine? ⇒ Boolean
private
Returns if this relation is combined aka a relation graph.
-
#combine_children(options) ⇒ RelationProxy
included
from Combine
Shortcut for combining with children which infers the join keys.
-
#combine_parents(options) ⇒ RelationProxy
included
from Combine
Shortcut for combining with parents which infers the join keys.
-
#combined(name, keys, type) ⇒ RelationProxy
included
from Combine
private
Returns a combine representation of a loading-proxy relation.
-
#composite? ⇒ Boolean
private
Return if this relation is a composite.
-
#inspect ⇒ String
Return a string representation of this relation proxy.
-
#map_with(*names, **opts) ⇒ RelationProxy
(also: #as)
Maps the wrapped relation with other mappers available in the registry.
-
#mapper ⇒ ROM::Mapper
private
Infers a mapper for the wrapped relation.
-
#name ⇒ ROM::Relation::Name
Relation name.
-
#node(name) {|The| ... } ⇒ RelationProxy
Return a new graph with adjusted node returned from a block.
- #respond_to_missing?(meth, _include_private = false) ⇒ Boolean private
-
#to_ast ⇒ Array
private
Returns AST for the wrapped relation.
-
#with(new_options) ⇒ RelationProxy
private
Returns a new instance with new options.
-
#wrap(*names, **options) ⇒ RelationProxy
included
from Wrap
Wrap other relations.
-
#wrap_parent(options) ⇒ RelationProxy
included
from Wrap
Shortcut to wrap parents.
-
#wrapped(name, keys, wrap_from_assoc = false) ⇒ RelationProxy
included
from Wrap
private
Return a wrapped representation of a loading-proxy relation.
- #wraps_from_names(names) ⇒ Object included from Wrap private
- #wraps_from_options(options) ⇒ Object included from Wrap private
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(meth, *args, &block) ⇒ Object (private)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Forward to relation and wrap it with proxy if response was a relation too
TODO: this will be simplified once ROM::Relation has lazy-features built-in
and ROM::Lazy is gone
284 285 286 287 288 289 290 291 292 293 294 295 296 |
# File 'lib/rom/repository/relation_proxy.rb', line 284 def method_missing(meth, *args, &block) if relation.respond_to?(meth) result = relation.__send__(meth, *args, &block) if result.kind_of?(Relation::Materializable) && !result.is_a?(Relation::Loaded) __new__(result) else result end else raise NoMethodError, "undefined method `#{meth}' for #{relation.class.name}" end end |
Instance Attribute Details
#relation ⇒ Relation, ... (readonly)
Returns The decorated relation object.
27 |
# File 'lib/rom/repository/relation_proxy.rb', line 27 param :relation |
Instance Method Details
#adapter ⇒ Symbol
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns The wrapped relation’s adapter identifier ie :sql or :http.
194 195 196 |
# File 'lib/rom/repository/relation_proxy.rb', line 194 def adapter relation.class.adapter end |
#call(*args) ⇒ Object
Materializes wrapped relation and sends it through a mapper
For performance reasons a combined relation will skip mapping since we only care about extracting key values for combining
50 51 52 |
# File 'lib/rom/repository/relation_proxy.rb', line 50 def call(*args) ((combine? || composite?) ? relation : (relation >> mapper)).call(*args) end |
#combine(*associations) ⇒ RelationProxy #combine(options) ⇒ RelationProxy Originally defined in module Combine
Combine with other relations
#combine? ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns if this relation is combined aka a relation graph
178 179 180 |
# File 'lib/rom/repository/relation_proxy.rb', line 178 def combine? [:combine_type] end |
#combine_children(options) ⇒ RelationProxy Originally defined in module Combine
Shortcut for combining with children which infers the join keys
#combine_parents(options) ⇒ RelationProxy Originally defined in module Combine
Shortcut for combining with parents which infers the join keys
#combined(name, keys, type) ⇒ RelationProxy Originally defined in module Combine
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a combine representation of a loading-proxy relation
This will carry meta info used to produce a correct AST from a relation so that correct mapper can be generated
#composite? ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Return if this relation is a composite
187 188 189 |
# File 'lib/rom/repository/relation_proxy.rb', line 187 def composite? relation.is_a?(Relation::Composite) end |
#inspect ⇒ String
Return a string representation of this relation proxy
149 150 151 |
# File 'lib/rom/repository/relation_proxy.rb', line 149 def inspect %(#<#{relation.class} name=#{name} dataset=#{dataset.inspect}>) end |
#map_with(model) ⇒ RelationProxy #map_with(*mappers) ⇒ RelationProxy #map_with(*mappers, auto_map: true) ⇒ RelationProxy Also known as: as
Maps the wrapped relation with other mappers available in the registry
88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/rom/repository/relation_proxy.rb', line 88 def map_with(*names, **opts) if names.size == 1 && names[0].is_a?(Class) with(meta: .merge(model: names[0])) elsif names.size > 1 && names.any? { |name| name.is_a?(Class) } raise ArgumentError, 'using custom mappers and a model is not supported' else if opts[:auto_map] && ![:combine_type] mappers = [mapper, *names.map { |name| relation.mappers[name] }] mappers.reduce(self) { |a, e| a >> e } else names.reduce(self) { |a, e| a >> relation.mappers[e] } end end end |
#mapper ⇒ ROM::Mapper
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Infers a mapper for the wrapped relation
158 159 160 |
# File 'lib/rom/repository/relation_proxy.rb', line 158 def mapper mappers[to_ast] end |
#name ⇒ ROM::Relation::Name
Relation name
40 41 42 |
# File 'lib/rom/repository/relation_proxy.rb', line 40 def name @name ? relation.name.with(@name) : relation.name end |
#node(name) {|The| ... } ⇒ RelationProxy
Return a new graph with adjusted node returned from a block
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/rom/repository/relation_proxy.rb', line 120 def node(name, &block) if name.is_a?(Symbol) && !nodes.map { |n| n.name.relation }.include?(name) raise ArgumentError, "#{name.inspect} is not a valid aggregate node name" end new_nodes = nodes.map { |node| case name when Symbol name == node.name.relation ? yield(node) : node when Hash other, *rest = name.flatten(1) if other == node.name.relation nodes.detect { |n| n.name.relation == other }.node(*rest, &block) else node end else node end } with_nodes(new_nodes) end |
#respond_to_missing?(meth, _include_private = false) ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
219 220 221 |
# File 'lib/rom/repository/relation_proxy.rb', line 219 def respond_to_missing?(meth, _include_private = false) relation.respond_to?(meth) || super end |
#to_ast ⇒ Array
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns AST for the wrapped relation
203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/rom/repository/relation_proxy.rb', line 203 def to_ast @to_ast ||= begin attr_ast = schema.map { |attr| [:attribute, attr] } = self..merge(dataset: base_name.dataset) .update(model: false) unless [:model] || auto_struct .delete(:wraps) header = attr_ast + nodes_ast + wraps_ast [:relation, [base_name.relation, , [:header, header]]] end end |
#with(new_options) ⇒ RelationProxy
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance with new options
169 170 171 |
# File 'lib/rom/repository/relation_proxy.rb', line 169 def with() __new__(relation, .merge()) end |
#wrap(*names, **options) ⇒ RelationProxy Originally defined in module Wrap
Wrap other relations
#wrap_parent(options) ⇒ RelationProxy Originally defined in module Wrap
Shortcut to wrap parents
#wrapped(name, keys, wrap_from_assoc = false) ⇒ RelationProxy Originally defined in module Wrap
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Return a wrapped representation of a loading-proxy relation
This will carry meta info used to produce a correct AST from a relation so that correct mapper can be generated
#wraps_from_names(names) ⇒ Object Originally defined in module Wrap
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
#wraps_from_options(options) ⇒ Object Originally defined in module Wrap
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.