Module: ROM::Relation::ClassInterface
- Extended by:
- Notifications::Listener
- Included in:
- ROM::Relation
- Defined in:
- lib/rom/relation/class_interface.rb
Overview
Global class-level API for relation classes
rubocop:disable Metrics/ModuleLength
Constant Summary collapse
- DEFAULT_DATASET_PROC =
-> * { self }.freeze
- INVALID_RELATIONS_NAMES =
[ :relations ].freeze
Instance Attribute Summary collapse
- #relation_name ⇒ Object readonly
- #schema_proc ⇒ Object readonly private
Instance Method Summary collapse
-
#[](adapter) ⇒ Class
Return adapter-specific relation subclass.
- #curried ⇒ Object private
-
#dataset(&block) ⇒ Object
Set or get custom dataset block.
-
#default_name ⇒ Name
private
Return default relation name used in schemas.
- #default_schema(klass = self) ⇒ Object private
-
#forward(*methods) ⇒ Object
Dynamically define a method that will forward to the dataset and wrap response in the relation itself.
-
#mapper_registry(opts = EMPTY_HASH) ⇒ MapperRegistry
private
Build default mapper registry.
- #name ⇒ Object private
-
#schema(dataset = nil, as: nil, infer: false) ⇒ Schema
Specify canonical schema for a relation.
- #schemas ⇒ Object private
-
#set_schema!(schema) ⇒ Schema
private
Assign a schema to a relation class.
-
#use(plugin, **options) ⇒ Object
Include a registered plugin in this relation class.
-
#view(*args, &block) ⇒ Symbol
Define a relation view with a specific schema.
- #view_methods ⇒ Object private
Methods included from Notifications::Listener
Instance Attribute Details
#relation_name ⇒ Object (readonly)
138 139 140 141 142 |
# File 'lib/rom/relation/class_interface.rb', line 138 def relation_name raise MissingSchemaError, self unless defined?(@relation_name) @relation_name end |
#schema_proc ⇒ Object (readonly)
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.
134 135 136 |
# File 'lib/rom/relation/class_interface.rb', line 134 def schema_proc @schema_proc end |
Instance Method Details
#[](adapter) ⇒ Class
Return adapter-specific relation subclass
48 49 50 51 52 |
# File 'lib/rom/relation/class_interface.rb', line 48 def [](adapter) ROM.adapters.fetch(adapter).const_get(:Relation) rescue KeyError raise AdapterNotPresentError.new(adapter, :relation) end |
#curried ⇒ Object
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.
280 |
# File 'lib/rom/relation/class_interface.rb', line 280 def curried = Curried |
#dataset(&block) ⇒ Object
Set or get custom dataset block
This block will be evaluated when a relation is instantiated and registered in a relation registry.
65 66 67 68 69 70 71 |
# File 'lib/rom/relation/class_interface.rb', line 65 def dataset(&block) if defined?(@dataset) @dataset else @dataset = block || DEFAULT_DATASET_PROC end end |
#default_name ⇒ Name
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 default relation name used in schemas
300 301 302 |
# File 'lib/rom/relation/class_interface.rb', line 300 def default_name Name[Inflector.underscore(name).tr('/', '_').to_sym] end |
#default_schema(klass = self) ⇒ Object
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.
305 306 307 308 309 310 311 312 |
# File 'lib/rom/relation/class_interface.rb', line 305 def default_schema(klass = self) klass.schema || if klass.schema_proc klass.set_schema!(klass.schema_proc.call) else klass.schema_class.define(klass.default_name) end end |
#forward(*methods) ⇒ Object
Dynamically define a method that will forward to the dataset and wrap response in the relation itself
240 241 242 243 244 245 246 247 248 |
# File 'lib/rom/relation/class_interface.rb', line 240 def forward(*methods) methods.each do |method| class_eval(" def \#{method}(...) # def super_query(...)\n new(dataset.__send__(:\#{method}, ...)) # new(dataset.__send__(:super_query, ...))\n end # end\n RUBY\n end\nend\n", __FILE__, __LINE__ + 1) |
#mapper_registry(opts = EMPTY_HASH) ⇒ MapperRegistry
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.
Build default mapper registry
266 267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/rom/relation/class_interface.rb', line 266 def mapper_registry(opts = EMPTY_HASH) adapter_ns = ROM.adapters[adapter] compiler = if adapter_ns&.const_defined?(:MapperCompiler) adapter_ns.const_get(:MapperCompiler) else MapperCompiler end MapperRegistry.new({}, compiler: compiler.new(**opts), **opts) end |
#name ⇒ Object
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.
315 |
# File 'lib/rom/relation/class_interface.rb', line 315 def name = super || superclass.name |
#schema(dataset = nil, as: nil, infer: false) ⇒ Schema
Specify canonical schema for a relation
With a schema defined commands will set up a type-safe input handler automatically
rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/rom/relation/class_interface.rb', line 96 def schema(dataset = nil, as: nil, infer: false, &) if defined?(@schema) && !block_given? && !infer @schema elsif block_given? || infer raise MissingSchemaClassError, self unless schema_class ds_name = dataset || schema_opts.fetch(:dataset, default_name.dataset) relation = as || schema_opts.fetch(:relation, ds_name) raise InvalidRelationName, relation if invalid_relation_name?(relation) @relation_name = Name[relation, ds_name] @schema_proc = proc do |*args, &inner_block| schema_dsl.new( relation_name, schema_class: schema_class, attr_class: schema_attr_class, inferrer: schema_inferrer.with(enabled: infer), & ).call(*args, &inner_block) end end end |
#schemas ⇒ Object
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.
291 292 293 |
# File 'lib/rom/relation/class_interface.rb', line 291 def schemas @schemas ||= {} end |
#set_schema!(schema) ⇒ Schema
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.
Assign a schema to a relation class
129 130 131 |
# File 'lib/rom/relation/class_interface.rb', line 129 def set_schema!(schema) @schema = schema end |
#use(plugin, **options) ⇒ Object
Include a registered plugin in this relation class
257 258 259 |
# File 'lib/rom/relation/class_interface.rb', line 257 def use(plugin, **) ROM.plugin_registry[:relation].fetch(plugin, adapter).apply_to(self, **) end |
#view(name, schema, &block) ⇒ Symbol #view(name, &block) ⇒ Symbol
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**
rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/rom/relation/class_interface.rb', line 194 def view(*args, &block) if args.size == 1 && block.arity.positive? raise ArgumentError, 'schema attribute names must be provided as the second argument' end name, new_schema_fn, relation_block = if args.size == 1 ViewDSL.new(*args, schema, &block).call else [*args, block] end schemas[name] = if args.size == 2 -> _ { schema.project(*args[1]) } else new_schema_fn end if relation_block.arity.positive? auto_curry_guard do define_method(name, &relation_block) auto_curry(name) do schemas[name].(self) end end else define_method(name) do schemas[name].(instance_exec(&relation_block)) end end name end |
#view_methods ⇒ Object
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.
283 284 285 286 287 288 |
# File 'lib/rom/relation/class_interface.rb', line 283 def view_methods ancestor_methods = ancestors.reject { |klass| klass == self } .map(&:instance_methods).flatten(1) instance_methods - ancestor_methods + auto_curried_methods.to_a end |