rom 5.4.2 → 6.0.0.alpha1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +58 -71
- data/LICENSE +1 -1
- data/README.md +7 -6
- data/lib/rom/array_dataset.rb +46 -0
- data/lib/rom/associations/abstract.rb +217 -0
- data/lib/rom/associations/definitions/abstract.rb +150 -0
- data/lib/rom/associations/definitions/many_to_many.rb +29 -0
- data/lib/rom/associations/definitions/many_to_one.rb +14 -0
- data/lib/rom/associations/definitions/one_to_many.rb +14 -0
- data/lib/rom/associations/definitions/one_to_one.rb +14 -0
- data/lib/rom/associations/definitions/one_to_one_through.rb +14 -0
- data/lib/rom/associations/definitions.rb +7 -0
- data/lib/rom/associations/many_to_many.rb +128 -0
- data/lib/rom/associations/many_to_one.rb +65 -0
- data/lib/rom/associations/one_to_many.rb +65 -0
- data/lib/rom/associations/one_to_one.rb +13 -0
- data/lib/rom/associations/one_to_one_through.rb +13 -0
- data/lib/rom/associations/through_identifier.rb +41 -0
- data/lib/rom/attribute.rb +425 -0
- data/lib/rom/auto_curry.rb +70 -0
- data/lib/rom/cache.rb +87 -0
- data/lib/rom/changeset/associated.rb +110 -0
- data/lib/rom/changeset/create.rb +18 -0
- data/lib/rom/changeset/delete.rb +15 -0
- data/lib/rom/changeset/extensions/relation.rb +26 -0
- data/lib/rom/changeset/pipe.rb +81 -0
- data/lib/rom/changeset/pipe_registry.rb +27 -0
- data/lib/rom/changeset/stateful.rb +285 -0
- data/lib/rom/changeset/update.rb +81 -0
- data/lib/rom/changeset.rb +185 -0
- data/lib/rom/command.rb +351 -0
- data/lib/rom/command_compiler.rb +201 -0
- data/lib/rom/command_proxy.rb +36 -0
- data/lib/rom/commands/class_interface.rb +236 -0
- data/lib/rom/commands/composite.rb +55 -0
- data/lib/rom/commands/create.rb +15 -0
- data/lib/rom/commands/delete.rb +16 -0
- data/lib/rom/commands/graph/class_interface.rb +64 -0
- data/lib/rom/commands/graph/input_evaluator.rb +94 -0
- data/lib/rom/commands/graph.rb +88 -0
- data/lib/rom/commands/lazy/create.rb +35 -0
- data/lib/rom/commands/lazy/delete.rb +39 -0
- data/lib/rom/commands/lazy/update.rb +46 -0
- data/lib/rom/commands/lazy.rb +106 -0
- data/lib/rom/commands/update.rb +16 -0
- data/lib/rom/commands.rb +5 -0
- data/lib/rom/compat/auto_registration.rb +115 -0
- data/lib/rom/compat/auto_registration_strategies/base.rb +29 -0
- data/lib/rom/compat/auto_registration_strategies/custom_namespace.rb +84 -0
- data/lib/rom/compat/auto_registration_strategies/no_namespace.rb +33 -0
- data/lib/rom/compat/auto_registration_strategies/with_namespace.rb +29 -0
- data/lib/rom/compat/command.rb +74 -0
- data/lib/rom/compat/components/dsl/schema.rb +130 -0
- data/lib/rom/compat/components.rb +91 -0
- data/lib/rom/compat/global.rb +17 -0
- data/lib/rom/compat/mapper.rb +22 -0
- data/lib/rom/compat/registries.rb +47 -0
- data/lib/rom/compat/relation.rb +40 -0
- data/lib/rom/compat/schema/dsl.rb +260 -0
- data/lib/rom/compat/setting_proxy.rb +44 -0
- data/lib/rom/compat/setup.rb +151 -0
- data/lib/rom/compat/transformer.rb +49 -0
- data/lib/rom/compat.rb +22 -0
- data/lib/rom/components/association.rb +26 -0
- data/lib/rom/components/command.rb +24 -0
- data/lib/rom/components/core.rb +148 -0
- data/lib/rom/components/dataset.rb +60 -0
- data/lib/rom/components/dsl/association.rb +47 -0
- data/lib/rom/components/dsl/command.rb +60 -0
- data/lib/rom/components/dsl/core.rb +126 -0
- data/lib/rom/components/dsl/dataset.rb +33 -0
- data/lib/rom/components/dsl/gateway.rb +14 -0
- data/lib/rom/components/dsl/mapper.rb +70 -0
- data/lib/rom/components/dsl/relation.rb +49 -0
- data/lib/rom/components/dsl/schema.rb +150 -0
- data/lib/rom/components/dsl/view.rb +82 -0
- data/lib/rom/components/dsl.rb +255 -0
- data/lib/rom/components/gateway.rb +50 -0
- data/lib/rom/components/mapper.rb +29 -0
- data/lib/rom/components/provider.rb +160 -0
- data/lib/rom/components/registry.rb +154 -0
- data/lib/rom/components/relation.rb +41 -0
- data/lib/rom/components/schema.rb +61 -0
- data/lib/rom/components/view.rb +55 -0
- data/lib/rom/components.rb +55 -0
- data/lib/rom/configuration_dsl.rb +4 -0
- data/lib/rom/constants.rb +135 -0
- data/lib/rom/container.rb +182 -0
- data/lib/rom/core.rb +125 -0
- data/lib/rom/data_proxy.rb +97 -0
- data/lib/rom/enumerable_dataset.rb +70 -0
- data/lib/rom/gateway.rb +232 -0
- data/lib/rom/global.rb +56 -0
- data/lib/rom/header/attribute.rb +190 -0
- data/lib/rom/header.rb +198 -0
- data/lib/rom/inferrer.rb +55 -0
- data/lib/rom/initializer.rb +80 -0
- data/lib/rom/lint/enumerable_dataset.rb +56 -0
- data/lib/rom/lint/gateway.rb +120 -0
- data/lib/rom/lint/linter.rb +79 -0
- data/lib/rom/lint/spec.rb +22 -0
- data/lib/rom/lint/test.rb +98 -0
- data/lib/rom/loader.rb +161 -0
- data/lib/rom/mapper/attribute_dsl.rb +480 -0
- data/lib/rom/mapper/dsl.rb +107 -0
- data/lib/rom/mapper/model_dsl.rb +61 -0
- data/lib/rom/mapper.rb +99 -0
- data/lib/rom/mapper_compiler.rb +84 -0
- data/lib/rom/memory/associations/many_to_many.rb +12 -0
- data/lib/rom/memory/associations/many_to_one.rb +12 -0
- data/lib/rom/memory/associations/one_to_many.rb +12 -0
- data/lib/rom/memory/associations/one_to_one.rb +12 -0
- data/lib/rom/memory/associations.rb +6 -0
- data/lib/rom/memory/commands.rb +60 -0
- data/lib/rom/memory/dataset.rb +127 -0
- data/lib/rom/memory/gateway.rb +66 -0
- data/lib/rom/memory/mapper_compiler.rb +10 -0
- data/lib/rom/memory/relation.rb +91 -0
- data/lib/rom/memory/schema.rb +32 -0
- data/lib/rom/memory/storage.rb +61 -0
- data/lib/rom/memory/types.rb +11 -0
- data/lib/rom/memory.rb +7 -0
- data/lib/rom/model_builder.rb +103 -0
- data/lib/rom/open_struct.rb +112 -0
- data/lib/rom/pipeline.rb +111 -0
- data/lib/rom/plugin.rb +130 -0
- data/lib/rom/plugins/class_methods.rb +37 -0
- data/lib/rom/plugins/command/schema.rb +45 -0
- data/lib/rom/plugins/command/timestamps.rb +149 -0
- data/lib/rom/plugins/dsl.rb +53 -0
- data/lib/rom/plugins/relation/changeset.rb +97 -0
- data/lib/rom/plugins/relation/instrumentation.rb +66 -0
- data/lib/rom/plugins/relation/registry_reader.rb +36 -0
- data/lib/rom/plugins/schema/timestamps.rb +59 -0
- data/lib/rom/plugins.rb +100 -0
- data/lib/rom/processor/composer.rb +37 -0
- data/lib/rom/processor/transformer.rb +415 -0
- data/lib/rom/processor.rb +30 -0
- data/lib/rom/registries/associations.rb +26 -0
- data/lib/rom/registries/commands.rb +11 -0
- data/lib/rom/registries/container.rb +12 -0
- data/lib/rom/registries/datasets.rb +21 -0
- data/lib/rom/registries/gateways.rb +8 -0
- data/lib/rom/registries/mappers.rb +21 -0
- data/lib/rom/registries/nestable.rb +32 -0
- data/lib/rom/registries/relations.rb +8 -0
- data/lib/rom/registries/root.rb +203 -0
- data/lib/rom/registries/schemas.rb +44 -0
- data/lib/rom/registries/views.rb +11 -0
- data/lib/rom/relation/class_interface.rb +61 -0
- data/lib/rom/relation/combined.rb +160 -0
- data/lib/rom/relation/commands.rb +65 -0
- data/lib/rom/relation/composite.rb +53 -0
- data/lib/rom/relation/curried.rb +129 -0
- data/lib/rom/relation/graph.rb +107 -0
- data/lib/rom/relation/loaded.rb +136 -0
- data/lib/rom/relation/materializable.rb +62 -0
- data/lib/rom/relation/name.rb +122 -0
- data/lib/rom/relation/wrap.rb +64 -0
- data/lib/rom/relation.rb +625 -0
- data/lib/rom/repository/class_interface.rb +162 -0
- data/lib/rom/repository/relation_reader.rb +48 -0
- data/lib/rom/repository/root.rb +75 -0
- data/lib/rom/repository/session.rb +60 -0
- data/lib/rom/repository.rb +179 -0
- data/lib/rom/schema/associations_dsl.rb +222 -0
- data/lib/rom/schema/inferrer.rb +106 -0
- data/lib/rom/schema.rb +471 -0
- data/lib/rom/settings.rb +141 -0
- data/lib/rom/setup.rb +297 -0
- data/lib/rom/struct.rb +99 -0
- data/lib/rom/struct_compiler.rb +114 -0
- data/lib/rom/support/configurable.rb +213 -0
- data/lib/rom/support/inflector.rb +31 -0
- data/lib/rom/support/memoizable.rb +61 -0
- data/lib/rom/support/notifications.rb +238 -0
- data/lib/rom/transaction.rb +26 -0
- data/lib/rom/transformer.rb +46 -0
- data/lib/rom/types.rb +74 -0
- data/lib/rom/version.rb +1 -1
- data/lib/rom-changeset.rb +4 -0
- data/lib/rom-core.rb +3 -0
- data/lib/rom-repository.rb +4 -0
- data/lib/rom.rb +3 -3
- metadata +302 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3dd988f906dce6d2688a81ef514a35dcf5661708a02381bcc929950b9ffee9ee
|
4
|
+
data.tar.gz: 63cf0036ba18ce38385b915bb9ac44b6a022cb6066575a596f675fe15a485dac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7dccbadae0c2c95428bb7303a7afca7f878d72ce6ac0824dc8002bf4d6d9bba950d0e50ea3d74e53ec2b8edf157c58315e3b584180009c9b2f0d1e3e423fed13
|
7
|
+
data.tar.gz: bb9a618db56d1d3f803b17f8390261f50e4c0a381fc8b8e7090ed6efce288daa5adaeddd6c01c8900f0117cdb86276d2d3c73335956f88a141c62268a25f1431
|
data/CHANGELOG.md
CHANGED
@@ -1,98 +1,85 @@
|
|
1
|
-
|
1
|
+
<!--- DO NOT EDIT THIS FILE - IT'S AUTOMATICALLY GENERATED VIA DEVTOOLS --->
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
- [rom-repository] Fix warning about redefined `set_relation` method (@flash-gordon)
|
6
|
-
|
7
|
-
## 5.4.1 2025-01-09
|
8
|
-
|
9
|
-
### Fixed
|
10
|
-
|
11
|
-
- [rom-repository] `set_relation` is deprecated and will be removed in 6.0.0 (issue #698 fixed via #699) (@flash-gordon)
|
12
|
-
|
13
|
-
## 5.4.0 2025-01-08
|
14
|
-
|
15
|
-
### Fixed
|
16
|
-
|
17
|
-
- [rom-repository] reduce memory allocation for relations reader in repository and regisry reader (issue #694 fixed via #695 and #695 and #697) (@flash-gordon)
|
18
|
-
|
19
|
-
### Changed
|
20
|
-
|
21
|
-
- [rom-core] Ruby 3.1 is now the minimum supported version (@flash-gordon)
|
22
|
-
|
23
|
-
[Compare v5.3.2...v5.4.0](https://github.com/rom-rb/rom/compare/v5.3.2...v5.4.0)
|
24
|
-
|
25
|
-
## 5.3.2 2024-05-06
|
26
|
-
|
27
|
-
### Fixed
|
28
|
-
|
29
|
-
- [rom-core] another fix caused by `Object#with` from ActiveSupport 7.1 (@flash-gordon)
|
30
|
-
|
31
|
-
[Compare v5.3.1...v5.3.2](https://github.com/rom-rb/rom/compare/v5.3.1...v5.3.2)
|
32
|
-
|
33
|
-
## 5.3.1 2024-03-15
|
34
|
-
|
35
|
-
### Changed
|
36
|
-
|
37
|
-
- [rom-core] workaround for compatibility with `Object#with` added in ActiveSupport 7.1 (@rykov + @flash-gordon)
|
3
|
+
## 6.0.0.alpha1 2022-04-15
|
38
4
|
|
39
|
-
[
|
5
|
+
This is a major release but it's backward compatible. Please see [the upgrade guide](https://github.com/rom-rb/rom/wiki/6.0-Upgrade-Guide) as there are
|
6
|
+
a couple of extra steps required for the upgrade.
|
40
7
|
|
41
|
-
## 5.3.0 2022-11-11
|
42
8
|
|
43
|
-
###
|
9
|
+
### Added
|
44
10
|
|
45
|
-
-
|
11
|
+
- New settings API for components using dry-configurable (via #651) (@solnic)
|
12
|
+
- ROM(...) shortcut method for setting up rom, ie `ROM(:sql, "sqlite::memory")` (@solnic)
|
13
|
+
- You can now configure a custom inflector via configuration (PR #591) (@flash-gordon)
|
14
|
+
- New component API that replaces internal implementation of the finalization code and makes it possible to extend ROM with arbitrary component types (see #637) (@solnic)
|
15
|
+
- Generic Component API which allows you to turn any class or object into a DSL that can define rom components (via #650) (@solnic)
|
16
|
+
- Support for defining abstract components via `config.component.abstract` in which case they won't be initialized for runtime usage (via #651) (@solnic)
|
17
|
+
- Ability to provide top-level component configuration ie default gateway, adapter, inflector etc. (via #653) (@solnic)
|
18
|
+
- Ability to configure gateways using configuration DSL (via #653) (@solnic)
|
19
|
+
- Ability to define schemas without relations (via #653) (@solnic)
|
20
|
+
- Relation view schemas that are defined via `Relation.view` DSL are now registered too, which makes them more accessible/reusable (via #653) (@solnic)
|
21
|
+
- Global configuration that can provide default settings for all your components. ie a default adapter, gateway etc. (via #654) (@solnic)
|
22
|
+
- Support for custom namespaces under which commands and mappers can be registered (via #654) (@solnic)
|
23
|
+
- Top-level `associations` DSL (via #656) (@solnic)
|
24
|
+
- Support for configuring plugins on a per-component *instance* basis, which means that implementing plugins is now simpler and more powerful (via #656) (@solnic)
|
25
|
+
- New relation setting: `component.infer_id_from_class` (via #661) (@solnic)
|
26
|
+
- [experimental] New `ROM.components` API for registering custom component types (via #654) (@solnic)
|
27
|
+
- .transaction methods now accept keyword arguments. `Repository#transaction` accepts gateway to use. `Repository::Root#transaction` uses a gateway of the root relation by default (#620 closed by #621) (@flash-gordon)
|
28
|
+
- Backward-compatibility extension that you can load via `require "rom/compat"` (via #634 refs #607) (@solnic)
|
46
29
|
|
47
30
|
### Fixed
|
48
31
|
|
49
|
-
-
|
50
|
-
|
51
|
-
[Compare v5.2.6...v5.3.0](https://github.com/rom-rb/rom/compare/v5.2.6...v5.3.0)
|
52
|
-
|
53
|
-
## 5.2.6 2021-01-16
|
32
|
+
- Setup works under MRI 3.0.0 (issue #622 fixed via #623) (@v-kolesnikov)
|
54
33
|
|
55
34
|
### Changed
|
56
35
|
|
57
|
-
- [
|
36
|
+
- [BREAKING] `rom-core`, `rom-changeset` and `rom-repository` have been merged into `rom` gem (@solnic)
|
37
|
+
- [BREAKING] `Setup#auto_registration` was renamed to `Setup#auto_register`. You can restore the original method via rom/compat extension (via #634 refs #607) (@solnic)
|
38
|
+
- [BREAKING] `Configuration#method_missing` no longer resolves gateways by default. This functionality was moved to rom/compat (@solnic)
|
39
|
+
- [BREAKING] `ROM::Configuration` is deprecated and it was replaced by `ROM::Setup`. It can be restored via rom/compat (via #653) (@solnic)
|
40
|
+
- `ROM.container` is deprecated and it was replaced by `ROM.runtime` (via #653) (@solnic)
|
41
|
+
- `Schema#[]` and `Relation#[]` now raise an error if a given attribute is not unique (issue #529 fixed via #543) (@waiting-for-dev)
|
42
|
+
- Configuration values are no longer being frozen during setup process (issue #616 fixed via #617) (@v-kolesnikov)
|
43
|
+
- Custom commands are now lazily-resolved at runtime, which simplifies and speeds up setup and finalization (via #641) (@solnic)
|
44
|
+
- Mappers are now lazy-resolved at runtime which speeds up setup and finalization (via #642) (@solnic)
|
45
|
+
- Schemas are now 1st class components accessible via runtime container and decoupled from relations (via #644) (@solnic)
|
46
|
+
- `Relation.dataset` receives canonical schema object now, rather than relation class (via #644) (@solnic)
|
47
|
+
- Relation classes no holder hold their schemas as class variables (via #644) (@solnic)
|
48
|
+
- Gateways are now lazy-loadable (via #645) (@solnic)
|
49
|
+
- Associations are now decoupled from schemas and lazy-loaded (via #646) (@solnic)
|
50
|
+
- Plugin API is now internally simplified which resulted in faster runtime. It's also no longer required to register plugin types upfront (via #648) (@solnic)
|
51
|
+
- Configuring auto_register stores its config under `config.auto_register` (via #650) (@solnic)
|
52
|
+
- [internal] auto registration is now powered by Zeitwerk (via #634 refs #607) (@solnic)
|
53
|
+
- Plugin event listeners are no longer global which makes it possible to have plugin with different configs in a single process (via #639) (@solnic)
|
54
|
+
- [internal] Command compiler is no longer coupled to gateway and notifications (via #640) (@solnic)
|
55
|
+
- Plugin configurations **are no longer global** which means that you can configure the same plugin with different default settings for different component groups or different runtimes in the same Ruby process (via #654) (@solnic)
|
56
|
+
- `Schema::DSL` is now deprecated. Adapters that need customized schema DSL behavior can provide plugins instead (via #656) (@solnic)
|
57
|
+
- `ROM.plugins` returns global plugin registry when called without a block (via #660) (@solnic)
|
58
|
+
- [internal] `ROM::Container` is deprecated and it was replaced by `ROM::Registries::Root`. It can be restored via rom/compat (via #653) (@solnic)
|
59
|
+
- [internal] Commands that are compiled at runtime are now cached in the runtime registry (via #653) (@solnic)
|
60
|
+
- [internal] `ROM.plugin_registry` is deprecated, use `ROM.plugins` instead (via #660) (@solnic)
|
61
|
+
- [REVISIT] configuring custom gateway for a relation via DSL requires passing it as an option rather than specifying it within the block. It kinda-worked previously because the adapter was defaulting to the first one found. I'm quite sure this was more like a bug than a feature. This behavior could be restored in rom/compat though - it's a matter of defaulting to the first adapter found when gateway was not explicitly specified, meaning the new default should be set to `Undefined` rather than `:default` so that we can detect when it was not specified and act accordingly. This will only make sense when there's just *one adapter available* (via bedb330f0ec195d9acacf4481dad3a705e8a36af) (@solnic)
|
62
|
+
|
63
|
+
[Compare v5.2.4...v6.0.0.alpha1](https://github.com/rom-rb/rom/compare/v5.2.4...v6.0.0.alpha1)
|
58
64
|
|
59
|
-
|
60
|
-
|
61
|
-
- [rom-core] Setup works under MRI 3.0.0 (issue #622 fixed via #623) (@v-kolesnikov)
|
62
|
-
|
63
|
-
[Compare v5.2.5...v5.2.6](https://github.com/rom-rb/rom/compare/v5.2.5...v5.2.6)
|
65
|
+
## 5.2.4 2020-05-08
|
64
66
|
|
65
|
-
## 5.2.5 2020-12-30
|
66
67
|
|
67
68
|
### Fixed
|
68
69
|
|
69
|
-
- [rom
|
70
|
-
- [rom-core] configuration values are no longer being frozen during finalization of the setup (@v-kolesnikov)
|
70
|
+
- [rom] Bumped rom-changeset version (@flash-gordon)
|
71
71
|
|
72
|
-
### Changed
|
73
|
-
|
74
|
-
- [rom] Dependency on `rom-core` was bumped to `>= 5.2.4` (@solnic)
|
75
|
-
|
76
|
-
[Compare v5.2.4...v5.2.5](https://github.com/rom-rb/rom/compare/v5.2.4...v5.2.5)
|
77
|
-
|
78
|
-
## 5.2.4 2020-05-08
|
79
|
-
|
80
|
-
### Changed
|
81
|
-
|
82
|
-
- [rom] Dependency on `rom-changeset` was bumped to `>= 5.2.3` (@flash-gordon)
|
83
72
|
|
84
73
|
[Compare v5.2.3...v5.2.4](https://github.com/rom-rb/rom/compare/v5.2.3...v5.2.4)
|
85
74
|
|
86
75
|
## 5.2.3 2020-05-07
|
87
76
|
|
88
|
-
### Fixed
|
89
77
|
|
90
|
-
|
91
|
-
- [rom-changeset] fix binding mapping functions in `Update` changesets (@timriley & @flash-gordon)
|
78
|
+
### Fixed
|
92
79
|
|
93
|
-
|
80
|
+
- [rom-core] Constructor types were fired twice when updating data (@flash-gordon)
|
81
|
+
- [rom-changeset] fixed a regression where a map function in `Update` changesets was not evaluated in the context of a changeset object (fixed via #592) (@timriley + @solnic)
|
94
82
|
|
95
|
-
- [rom] Dependency on `rom-core` was bumped to `>= 5.2.3` (@solnic)
|
96
83
|
|
97
84
|
[Compare v5.2.2...v5.2.3](https://github.com/rom-rb/rom/compare/v5.2.2...v5.2.3)
|
98
85
|
|
@@ -317,4 +304,4 @@ Yanked and republished as 5.2.1
|
|
317
304
|
|
318
305
|
## 4.0.0 2017-10-18
|
319
306
|
|
320
|
-
This release turns `rom` gem into a meta gem which depends on `rom-core`, `rom-mapper`, `rom-repository` and `rom-changeset'`. See [CHANGELOG](https://github.com/rom-rb/rom/blob/
|
307
|
+
This release turns `rom` gem into a meta gem which depends on `rom-core`, `rom-mapper`, `rom-repository` and `rom-changeset'`. See [CHANGELOG](https://github.com/rom-rb/rom/blob/main/core/CHANGELOG.md#v400-2017-10-18) in core for more information.
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
[][actions]
|
11
11
|
[][codacy]
|
12
12
|
[][codacy]
|
13
|
-
[][inchpages]
|
14
14
|
[](#backers)
|
15
15
|
[](#sponsors)
|
16
16
|
|
@@ -20,14 +20,14 @@ the full power of your database.
|
|
20
20
|
|
21
21
|
Main rom gem provides following components:
|
22
22
|
|
23
|
-
* [core](https://github.com/rom-rb/rom/blob/
|
24
|
-
* [changeset](https://github.com/rom-rb/rom/blob/
|
25
|
-
* [repository](https://github.com/rom-rb/rom/blob/
|
23
|
+
* [core](https://github.com/rom-rb/rom/blob/main/core/README.md) - Core and Adapter APIs
|
24
|
+
* [changeset](https://github.com/rom-rb/rom/blob/main/changeset/README.md) - Changeset objects integrated with rom-core
|
25
|
+
* [repository](https://github.com/rom-rb/rom/blob/main/repository/README.md) - Additional repository abstraction integrated with rom-core
|
26
26
|
|
27
27
|
Learn more:
|
28
28
|
|
29
|
-
* [Introduction](
|
30
|
-
* [Quick Start](
|
29
|
+
* [Introduction](https://rom-rb.org/learn/introduction)
|
30
|
+
* [Quick Start](https://rom-rb.org/learn/repository/5.2/quick-start/)
|
31
31
|
|
32
32
|
## Backers
|
33
33
|
|
@@ -104,6 +104,7 @@ Become a sponsor and get your logo on our README on Github with a link to your s
|
|
104
104
|
There are other gems within the rom ecosystem that you will find useful:
|
105
105
|
|
106
106
|
* [rom-factory](https://github.com/rom-rb/rom-factory) struct generator with support for persistence
|
107
|
+
* (WIP) [rom-migrator](https://github.com/rom-rb/rom-migrator) common APIs for database migrations
|
107
108
|
|
108
109
|
## Adapters
|
109
110
|
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rom/initializer"
|
4
|
+
require "rom/enumerable_dataset"
|
5
|
+
|
6
|
+
module ROM
|
7
|
+
# A helper module that adds data-proxy behavior to an array-like object
|
8
|
+
#
|
9
|
+
# @see EnumerableDataset
|
10
|
+
#
|
11
|
+
# @api public
|
12
|
+
module ArrayDataset
|
13
|
+
extend DataProxy::ClassMethods
|
14
|
+
include EnumerableDataset
|
15
|
+
|
16
|
+
# Extends the class with data-proxy behavior
|
17
|
+
#
|
18
|
+
# @api private
|
19
|
+
def self.included(klass)
|
20
|
+
klass.class_eval do
|
21
|
+
extend Initializer
|
22
|
+
include DataProxy
|
23
|
+
|
24
|
+
param :data
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
forward(
|
29
|
+
:*, :+, :-, :compact, :compact!, :flatten, :flatten!, :length, :pop,
|
30
|
+
:reverse, :reverse!, :sample, :size, :shift, :shuffle, :shuffle!,
|
31
|
+
:slice, :slice!, :sort!, :uniq, :uniq!, :unshift, :values_at
|
32
|
+
)
|
33
|
+
|
34
|
+
%i[
|
35
|
+
map! combination cycle delete_if keep_if permutation reject!
|
36
|
+
select! sort_by!
|
37
|
+
].each do |method|
|
38
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
39
|
+
def #{method}(*args, &block)
|
40
|
+
return to_enum unless block
|
41
|
+
self.class.new(data.send(:#{method}, *args, &block), **options)
|
42
|
+
end
|
43
|
+
RUBY
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,217 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/core/constants"
|
4
|
+
require "dry/core/class_attributes"
|
5
|
+
|
6
|
+
require "rom/types"
|
7
|
+
require "rom/initializer"
|
8
|
+
require "rom/support/memoizable"
|
9
|
+
|
10
|
+
module ROM
|
11
|
+
module Associations
|
12
|
+
# Abstract association class
|
13
|
+
#
|
14
|
+
# @api public
|
15
|
+
class Abstract
|
16
|
+
extend Initializer
|
17
|
+
|
18
|
+
include Memoizable
|
19
|
+
include Dry::Equalizer(:definition, :source, :target)
|
20
|
+
|
21
|
+
# @!attribute [r] definition
|
22
|
+
# @return [ROM::Associations::Definition] Association configuration object
|
23
|
+
param :definition
|
24
|
+
|
25
|
+
# @!attribute [r] relations
|
26
|
+
# @return [ROM::RelationRegistry] Relation registry
|
27
|
+
option :relations, reader: true
|
28
|
+
|
29
|
+
# @!attribute [r] source
|
30
|
+
# @return [ROM::Relation] The source relation
|
31
|
+
option :source, reader: false, optional: true
|
32
|
+
|
33
|
+
# @!attribute [r] target
|
34
|
+
# @return [ROM::Relation] The target relation
|
35
|
+
option :target, reader: false, optional: true
|
36
|
+
|
37
|
+
# Create an association object
|
38
|
+
#
|
39
|
+
# @param [Definition] definition The association definition object
|
40
|
+
# @param [RelationRegistry] relations The relation registry
|
41
|
+
#
|
42
|
+
# @api public
|
43
|
+
def self.new(definition, relations)
|
44
|
+
super(definition, relations: relations)
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [ROM::Relation] The source relation
|
48
|
+
#
|
49
|
+
# @api public
|
50
|
+
def source
|
51
|
+
options[:source] || relations[definition.source.relation]
|
52
|
+
end
|
53
|
+
|
54
|
+
# @return [ROM::Relation] The target relation
|
55
|
+
#
|
56
|
+
# @api public
|
57
|
+
def target
|
58
|
+
options[:target] || relations[definition.target.relation]
|
59
|
+
end
|
60
|
+
|
61
|
+
# Return if an association has an alias
|
62
|
+
#
|
63
|
+
# @return [Boolean]
|
64
|
+
#
|
65
|
+
# @api public
|
66
|
+
def aliased?
|
67
|
+
definition.aliased?
|
68
|
+
end
|
69
|
+
|
70
|
+
# Return association alias
|
71
|
+
#
|
72
|
+
# @return [Symbol]
|
73
|
+
#
|
74
|
+
# @api public
|
75
|
+
def as
|
76
|
+
definition.as
|
77
|
+
end
|
78
|
+
|
79
|
+
# Return association canonical name
|
80
|
+
#
|
81
|
+
# @return [Symbol]
|
82
|
+
#
|
83
|
+
# @api public
|
84
|
+
def name
|
85
|
+
definition.name
|
86
|
+
end
|
87
|
+
|
88
|
+
# Return the name of a custom relation view that should be use to
|
89
|
+
# extend or override default association view
|
90
|
+
#
|
91
|
+
# @return [Symbol]
|
92
|
+
#
|
93
|
+
# @api public
|
94
|
+
def view
|
95
|
+
definition.view
|
96
|
+
end
|
97
|
+
|
98
|
+
# Return association foreign key name
|
99
|
+
#
|
100
|
+
# @return [Symbol]
|
101
|
+
#
|
102
|
+
# @api public
|
103
|
+
def foreign_key
|
104
|
+
definition.foreign_key
|
105
|
+
end
|
106
|
+
|
107
|
+
# Return result type
|
108
|
+
#
|
109
|
+
# This can be either :one or :many
|
110
|
+
#
|
111
|
+
# @return [Symbol]
|
112
|
+
#
|
113
|
+
# @api public
|
114
|
+
def result
|
115
|
+
definition.result
|
116
|
+
end
|
117
|
+
|
118
|
+
# Return if a custom view should override default association view
|
119
|
+
#
|
120
|
+
# @return [Boolean]
|
121
|
+
#
|
122
|
+
# @api public
|
123
|
+
def override?
|
124
|
+
definition.override
|
125
|
+
end
|
126
|
+
|
127
|
+
# Return the name of a key in tuples under which loaded association data are returned
|
128
|
+
#
|
129
|
+
# @return [Symbol]
|
130
|
+
#
|
131
|
+
# @api public
|
132
|
+
def key
|
133
|
+
as || name
|
134
|
+
end
|
135
|
+
|
136
|
+
# Applies custom view to the default association view
|
137
|
+
#
|
138
|
+
# @return [Relation]
|
139
|
+
#
|
140
|
+
# @api protected
|
141
|
+
def apply_view(schema, relation)
|
142
|
+
view_rel = relation.public_send(view)
|
143
|
+
schema.merge(view_rel.schema).uniq(&:key).(view_rel)
|
144
|
+
end
|
145
|
+
|
146
|
+
# Return combine keys hash
|
147
|
+
#
|
148
|
+
# Combine keys are used for merging associated data together, typically these
|
149
|
+
# are the same as fk<=>pk mapping
|
150
|
+
#
|
151
|
+
# @return [Hash<Symbol=>Symbol>]
|
152
|
+
#
|
153
|
+
# @api public
|
154
|
+
def combine_keys
|
155
|
+
definition.combine_keys || {source_key => target_key}
|
156
|
+
end
|
157
|
+
|
158
|
+
# Return names of source PKs and target FKs
|
159
|
+
#
|
160
|
+
# @return [Array<Symbol>]
|
161
|
+
#
|
162
|
+
# @api private
|
163
|
+
def join_key_map
|
164
|
+
join_keys.to_a.flatten(1).map(&:key)
|
165
|
+
end
|
166
|
+
|
167
|
+
# Return target relation configured as a combine node
|
168
|
+
#
|
169
|
+
# @return [Relation]
|
170
|
+
#
|
171
|
+
# @api private
|
172
|
+
def node
|
173
|
+
target.with(
|
174
|
+
name: target.name.as(key),
|
175
|
+
meta: {keys: combine_keys, combine_type: result, combine_name: key}
|
176
|
+
)
|
177
|
+
end
|
178
|
+
|
179
|
+
# Return target relation as a wrap node
|
180
|
+
#
|
181
|
+
# @return [Relation]
|
182
|
+
#
|
183
|
+
# @api private
|
184
|
+
def wrap
|
185
|
+
target.with(
|
186
|
+
name: target.name.as(key),
|
187
|
+
schema: target.schema.wrap,
|
188
|
+
meta: {wrap: true, combine_name: key}
|
189
|
+
)
|
190
|
+
end
|
191
|
+
|
192
|
+
# Prepare association's target relation for composition
|
193
|
+
#
|
194
|
+
# @return [Relation]
|
195
|
+
#
|
196
|
+
# @api private
|
197
|
+
def prepare(target)
|
198
|
+
if override?
|
199
|
+
target.public_send(view)
|
200
|
+
else
|
201
|
+
call(target: target)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
# Return if this association's source relation is the same as the target
|
206
|
+
#
|
207
|
+
# @return [Boolean]
|
208
|
+
#
|
209
|
+
# @api private
|
210
|
+
def self_ref?
|
211
|
+
source.name.dataset == target.name.dataset
|
212
|
+
end
|
213
|
+
|
214
|
+
memoize :combine_keys, :join_key_map
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/core/class_attributes"
|
4
|
+
|
5
|
+
require "rom/constants"
|
6
|
+
require "rom/types"
|
7
|
+
require "rom/initializer"
|
8
|
+
require "rom/relation/name"
|
9
|
+
require "rom/associations/through_identifier"
|
10
|
+
require "rom/support/inflector"
|
11
|
+
|
12
|
+
module ROM
|
13
|
+
module Associations
|
14
|
+
module Definitions
|
15
|
+
# Abstract association definition object
|
16
|
+
#
|
17
|
+
# @api public
|
18
|
+
class Abstract
|
19
|
+
include Dry::Equalizer(:source, :target, :result)
|
20
|
+
extend Initializer
|
21
|
+
extend Dry::Core::ClassAttributes
|
22
|
+
|
23
|
+
defines :result
|
24
|
+
|
25
|
+
# @!attribute [r] source
|
26
|
+
# @return [Relation::Name] the source relation name
|
27
|
+
param :source
|
28
|
+
|
29
|
+
# @!attribute [r] target
|
30
|
+
# @return [Relation::Name] the target relation name
|
31
|
+
param :target
|
32
|
+
|
33
|
+
# @!attribute [r] name
|
34
|
+
# @return [Symbol] The name of an association
|
35
|
+
option :name, Types::Strict::Symbol, default: -> { target.to_sym }
|
36
|
+
|
37
|
+
# @!attribute [r] relation
|
38
|
+
# @return [Symbol] an optional relation identifier for the target
|
39
|
+
option :relation, Types::Strict::Symbol, default: -> { name }
|
40
|
+
|
41
|
+
# @!attribute [r] alias
|
42
|
+
# @return [Symbol] An optional association alias
|
43
|
+
option :as, Types::Strict::Symbol.optional, optional: true
|
44
|
+
|
45
|
+
# @!attribute [r] foreign_key
|
46
|
+
# @return [Symbol] an optional association alias name
|
47
|
+
option :foreign_key, Types::Optional::Strict::Symbol, optional: true
|
48
|
+
|
49
|
+
# @!attribute [r] result
|
50
|
+
# @return [Symbol] either :one or :many
|
51
|
+
option :result, Types::Strict::Symbol, default: -> { self.class.result }
|
52
|
+
|
53
|
+
# @!attribute [r] view
|
54
|
+
# @return [Symbol] An optional view that should be used to extend assoc relation
|
55
|
+
option :view, optional: true
|
56
|
+
|
57
|
+
# @!attribute [r] override
|
58
|
+
# @return [TrueClass,FalseClass] Whether custom view should override default one or not
|
59
|
+
option :override, default: -> { false }
|
60
|
+
|
61
|
+
# @!attribute [r] combine_keys
|
62
|
+
# @return [Hash<Symbol=>Symbol>] Override inferred combine keys
|
63
|
+
option :combine_keys, optional: true
|
64
|
+
|
65
|
+
# Instantiate a new association definition
|
66
|
+
#
|
67
|
+
# @param [Symbol] source The name of the source dataset
|
68
|
+
# @param [Symbol] target The name of the target dataset
|
69
|
+
# @param [Hash] opts The option hash
|
70
|
+
# @option opts [Symbol] :as The name of the association (defaults to target)
|
71
|
+
# @option opts [Symbol] :relation The name of the target relation (defaults to target)
|
72
|
+
# @option opts [Symbol] :foreign_key The name of a custom foreign key
|
73
|
+
# @option opts [Symbol] :view The name of a custom relation view on the target's relation side
|
74
|
+
# @option opts [TrueClass,FalseClass] :override Whether provided :view should override association's default view
|
75
|
+
#
|
76
|
+
# @api public
|
77
|
+
def self.new(source, target, **opts)
|
78
|
+
source_name = Relation::Name[source]
|
79
|
+
target_name = resolve_target_name(target, opts)
|
80
|
+
options = process_options(target_name, opts.to_h)
|
81
|
+
|
82
|
+
super(source_name, target_name, **options)
|
83
|
+
end
|
84
|
+
|
85
|
+
# @api private
|
86
|
+
def self.resolve_target_name(target, options)
|
87
|
+
dataset = target
|
88
|
+
relation = options.fetch(:relation, target)
|
89
|
+
|
90
|
+
Relation::Name[relation, dataset, options[:as]]
|
91
|
+
end
|
92
|
+
|
93
|
+
# @api private
|
94
|
+
def self.process_options(target, options)
|
95
|
+
through = options[:through]
|
96
|
+
|
97
|
+
if through
|
98
|
+
options[:through] = ThroughIdentifier[
|
99
|
+
through,
|
100
|
+
target.relation,
|
101
|
+
options[:assoc],
|
102
|
+
inflector: options.fetch(:inflector, Inflector)
|
103
|
+
]
|
104
|
+
end
|
105
|
+
|
106
|
+
options[:name] = target.relation
|
107
|
+
|
108
|
+
options
|
109
|
+
end
|
110
|
+
|
111
|
+
# @api public
|
112
|
+
def id
|
113
|
+
aliased? ? as : name
|
114
|
+
end
|
115
|
+
|
116
|
+
# @api public
|
117
|
+
def to_h
|
118
|
+
{id: id, **options}
|
119
|
+
end
|
120
|
+
|
121
|
+
# Return true if association's default relation view should be overridden by a custom one
|
122
|
+
#
|
123
|
+
# @return [Boolean]
|
124
|
+
#
|
125
|
+
# @api public
|
126
|
+
def override?
|
127
|
+
options[:override].equal?(true)
|
128
|
+
end
|
129
|
+
|
130
|
+
# Return true if association is aliased
|
131
|
+
#
|
132
|
+
# @return [Boolean]
|
133
|
+
#
|
134
|
+
# @api public
|
135
|
+
def aliased?
|
136
|
+
!options[:as].nil?
|
137
|
+
end
|
138
|
+
|
139
|
+
# Return association class for a given definition object
|
140
|
+
#
|
141
|
+
# @return [Class]
|
142
|
+
#
|
143
|
+
# @api public
|
144
|
+
def type
|
145
|
+
Inflector.demodulize(self.class.name).to_sym
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rom/types"
|
4
|
+
require "rom/associations/definitions/abstract"
|
5
|
+
|
6
|
+
module ROM
|
7
|
+
module Associations
|
8
|
+
module Definitions
|
9
|
+
# @api private
|
10
|
+
class ManyToMany < Abstract
|
11
|
+
result :many
|
12
|
+
|
13
|
+
# @!attribute [r] through
|
14
|
+
# @return [ThroughIdentifier] The name of the "through" relation
|
15
|
+
option :through, reader: true
|
16
|
+
|
17
|
+
# @api private
|
18
|
+
def through_relation
|
19
|
+
through.relation
|
20
|
+
end
|
21
|
+
|
22
|
+
# @api private
|
23
|
+
def through_assoc_name
|
24
|
+
through.assoc_name
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|