rom-factory 0.13.0 → 0.14.0
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 +78 -45
- data/LICENSE +1 -1
- data/README.md +12 -19
- data/lib/rom/factory/attributes/association.rb +157 -149
- data/lib/rom/factory/attributes/callable.rb +31 -28
- data/lib/rom/factory/attributes/sequence.rb +26 -23
- data/lib/rom/factory/attributes/value.rb +25 -22
- data/lib/rom/factory/builder.rb +68 -65
- data/lib/rom/factory/dsl.rb +18 -8
- data/lib/rom/factory/factories.rb +227 -225
- data/lib/rom/factory/tuple_evaluator.rb +10 -2
- data/lib/rom/factory/version.rb +1 -1
- data/rom-factory.gemspec +25 -20
- metadata +31 -39
- data/.devtools/templates/changelog.erb +0 -43
- data/.devtools/templates/release.erb +0 -36
- data/.github/FUNDING.yml +0 -1
- data/.github/ISSUE_TEMPLATE/bug-report.md +0 -26
- data/.github/ISSUE_TEMPLATE/config.yml +0 -5
- data/.github/SUPPORT.md +0 -3
- data/.github/workflows/ci.yml +0 -87
- data/.github/workflows/docsite.yml +0 -62
- data/.github/workflows/rubocop.yml +0 -46
- data/.github/workflows/sync_configs.yml +0 -47
- data/.gitignore +0 -10
- data/.postgres.env +0 -4
- data/.repobot.yml +0 -24
- data/.rspec +0 -4
- data/.rubocop.yml +0 -247
- data/.yardopts +0 -7
- data/CODE_OF_CONDUCT.md +0 -13
- data/CONTRIBUTING.md +0 -29
- data/Gemfile +0 -49
- data/Gemfile.devtools +0 -20
- data/Rakefile +0 -8
- data/benchmarks/basic.rb +0 -66
- data/changelog.yml +0 -134
- data/compose.yml +0 -7
- data/docsite/source/index.html.md +0 -181
- data/project.yml +0 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 76c2c2d443aae25366e10dc9cfb41bc23a9e69abd38597b144214a9b4f861b51
|
|
4
|
+
data.tar.gz: 3aea3e8cf8568962e72c0d8ebda1da5b9ca38b6bcbf6469a9c2ea3f67377a314
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1a463af2b73eca8c24d2a276c678a72e7d7883ed030b241bdc71c58998ce2ce0742f039e30744a0baa12d81cfcab111602f2b960e0db5abf786b3c0f9afe3c03
|
|
7
|
+
data.tar.gz: b60e2dfd2d87136bd3f10a84df790fa2f664babdd9d972682986545ceefabf7353f7811ef6f2f51028f611012e3b9f632cf485fcdf63c0d490ef543b9b59cf8d
|
data/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,53 @@
|
|
|
1
|
-
|
|
1
|
+
# Changelog
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Break Versioning](https://www.taoensso.com/break-versioning).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
### Deprecated
|
|
15
|
+
|
|
16
|
+
### Removed
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
### Security
|
|
21
|
+
|
|
22
|
+
[Unreleased]: https://github.com/rom-rb/rom-factory/compare/v0.14.0...main
|
|
23
|
+
|
|
24
|
+
## [0.14.0] - 2026-10-03
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- Support transient attributes. (@rickenharp in #97)
|
|
29
|
+
|
|
30
|
+
Define transient attributes inside a `transient` block. Other attributes can depend on them, but they are not part of the resulting tuple or struct. You can override them when building, like any other attribute.
|
|
31
|
+
|
|
32
|
+
```ruby
|
|
33
|
+
Factory.define(:user) do |f|
|
|
34
|
+
f.transient do |t|
|
|
35
|
+
t.password "secret"
|
|
36
|
+
end
|
|
37
|
+
f.password_hash { |password| BCrypt::Password.create(password) }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
Factory[:user, password: "something else"]
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
|
|
45
|
+
- Minimum Ruby version is now 3.3. (@alassek)
|
|
46
|
+
- Add `tsort` as an explicit runtime dependency. (@flash-gordon)
|
|
47
|
+
|
|
48
|
+
[0.13.0]: https://github.com/rom-rb/rom-factory/compare/v0.13.0...v0.14.0
|
|
49
|
+
|
|
50
|
+
## [0.13.0] - 2025-01-21
|
|
5
51
|
|
|
6
52
|
### Added
|
|
7
53
|
|
|
@@ -23,15 +69,18 @@ Factory.define :category do |f|
|
|
|
23
69
|
end
|
|
24
70
|
```
|
|
25
71
|
|
|
72
|
+
- Aliases for factory methods (via #92) (@cflipse)
|
|
73
|
+
|
|
74
|
+
`Factory.create` is aliased to `Factory.[]`
|
|
75
|
+
`Factory.build` is aliased to `Factory.structs[]`
|
|
26
76
|
|
|
27
77
|
### Changed
|
|
28
78
|
|
|
29
79
|
- Minimum Ruby version is now 3.1 (@flash-gordon)
|
|
30
80
|
|
|
31
|
-
[
|
|
32
|
-
|
|
33
|
-
## 0.12.0 2024-01-19
|
|
81
|
+
[0.13.0]: https://github.com/rom-rb/rom-factory/compare/v0.12.0...v0.13.0
|
|
34
82
|
|
|
83
|
+
## [0.12.0] - 2024-01-19
|
|
35
84
|
|
|
36
85
|
### Added
|
|
37
86
|
|
|
@@ -43,11 +92,9 @@ end
|
|
|
43
92
|
- Relations without PKs should work too (via #87) (@solnic)
|
|
44
93
|
- Relations with PK values generated on the Ruby side should work in SQlite too (via #87) (@solnic)
|
|
45
94
|
|
|
95
|
+
[0.12.0]: https://github.com/rom-rb/rom-factory/compare/v0.11.0...v0.12.0
|
|
46
96
|
|
|
47
|
-
[
|
|
48
|
-
|
|
49
|
-
## 0.11.0 2022-11-11
|
|
50
|
-
|
|
97
|
+
## [0.11.0] - 2022-11-11
|
|
51
98
|
|
|
52
99
|
### Added
|
|
53
100
|
|
|
@@ -80,20 +127,17 @@ Factory[:user, **user_attributes]
|
|
|
80
127
|
- Upgraded to the latest versions of dry-rb dependencies, compatible with rom 5.3 (@flash-gordon)
|
|
81
128
|
- Support for Faker 1.x was dropped (@alassek)
|
|
82
129
|
|
|
83
|
-
[
|
|
84
|
-
|
|
85
|
-
## 0.10.2 2020-04-05
|
|
130
|
+
[0.11.0]: https://github.com/rom-rb/rom-factory/compare/v0.10.2...v0.11.0
|
|
86
131
|
|
|
132
|
+
## [0.10.2] - 2020-04-05
|
|
87
133
|
|
|
88
134
|
### Fixed
|
|
89
135
|
|
|
90
136
|
- Fix more keyword warnings (@flash-gordon)
|
|
91
137
|
|
|
138
|
+
[0.10.2]: https://github.com/rom-rb/rom-factory/compare/v0.10.1...v0.10.2
|
|
92
139
|
|
|
93
|
-
[
|
|
94
|
-
|
|
95
|
-
## 0.10.1 2019-12-28
|
|
96
|
-
|
|
140
|
+
## [0.10.1] - 2019-12-28
|
|
97
141
|
|
|
98
142
|
### Added
|
|
99
143
|
|
|
@@ -103,11 +147,9 @@ Factory[:user, **user_attributes]
|
|
|
103
147
|
|
|
104
148
|
- Keyword warnings reported by Ruby 2.7 (@flash-gordon)
|
|
105
149
|
|
|
150
|
+
[0.10.1]: https://github.com/rom-rb/rom-factory/compare/v0.10.0...v0.10.1
|
|
106
151
|
|
|
107
|
-
[
|
|
108
|
-
|
|
109
|
-
## 0.10.0 2019-12-11
|
|
110
|
-
|
|
152
|
+
## [0.10.0] - 2019-12-11
|
|
111
153
|
|
|
112
154
|
### Added
|
|
113
155
|
|
|
@@ -124,41 +166,33 @@ Factory[:user, **user_attributes]
|
|
|
124
166
|
- Support building structs when child assoc does not define parent (@psparrow)
|
|
125
167
|
- Fixed `TupleEvaluator#struct_attrs` for non-standard output schema (@AMHOL)
|
|
126
168
|
|
|
169
|
+
[0.10.0]: https://github.com/rom-rb/rom-factory/compare/v0.9.1...v0.10.0
|
|
127
170
|
|
|
128
|
-
[
|
|
129
|
-
|
|
130
|
-
## 0.9.1 2019-10-23
|
|
131
|
-
|
|
171
|
+
## [0.9.1] - 2019-10-23
|
|
132
172
|
|
|
133
173
|
### Fixed
|
|
134
174
|
|
|
135
175
|
- Attributes of a struct are no longer accidentally passed to their associations (@psparrow)
|
|
136
176
|
|
|
177
|
+
[0.9.1]: https://github.com/rom-rb/rom-factory/compare/v0.9.0...v0.9.1
|
|
137
178
|
|
|
138
|
-
[
|
|
139
|
-
|
|
140
|
-
## 0.9.0 2019-08-12
|
|
141
|
-
|
|
179
|
+
## [0.9.0] - 2019-08-12
|
|
142
180
|
|
|
143
181
|
### Added
|
|
144
182
|
|
|
145
183
|
- When attributes hash includes unknown attributes, a `ROM::Factory::UnknownAttributeError` will be raised (@rawburt)
|
|
146
184
|
|
|
185
|
+
[0.9.0]: https://github.com/rom-rb/rom-factory/compare/v0.8.0...v0.9.0
|
|
147
186
|
|
|
148
|
-
[
|
|
149
|
-
|
|
150
|
-
## 0.8.0 2019-04-24
|
|
151
|
-
|
|
187
|
+
## [0.8.0] - 2019-04-24
|
|
152
188
|
|
|
153
189
|
### Fixed
|
|
154
190
|
|
|
155
191
|
- Loaded association structs are no longer rejected by output schemas (issue #34) (flash-gordon + solnic)
|
|
156
192
|
|
|
193
|
+
[0.8.0]: https://github.com/rom-rb/rom-factory/compare/v0.7.0...v0.8.0
|
|
157
194
|
|
|
158
|
-
[
|
|
159
|
-
|
|
160
|
-
## 0.7.0 2018-11-17
|
|
161
|
-
|
|
195
|
+
## [0.7.0] - 2018-11-17
|
|
162
196
|
|
|
163
197
|
### Added
|
|
164
198
|
|
|
@@ -169,11 +203,9 @@ Factory[:user, **user_attributes]
|
|
|
169
203
|
|
|
170
204
|
- Overwritten attributes with dependencies (JanaVPetrova)
|
|
171
205
|
|
|
206
|
+
[0.7.0]: https://github.com/rom-rb/rom-factory/compare/v0.6.0...v0.7.0
|
|
172
207
|
|
|
173
|
-
[
|
|
174
|
-
|
|
175
|
-
## 0.6.0 2018-01-31
|
|
176
|
-
|
|
208
|
+
## [0.6.0] - 2018-01-31
|
|
177
209
|
|
|
178
210
|
### Added
|
|
179
211
|
|
|
@@ -187,10 +219,9 @@ Factory[:user, **user_attributes]
|
|
|
187
219
|
|
|
188
220
|
- Accessing a factory which is not defined will result in `FactoryNotDefinedError` exception (GustavoCaso + solnic)
|
|
189
221
|
|
|
190
|
-
[
|
|
191
|
-
|
|
192
|
-
## 0.5.0 2017-10-24
|
|
222
|
+
[0.6.0]: https://github.com/rom-rb/rom-factory/compare/v0.5.0...v0.6.0
|
|
193
223
|
|
|
224
|
+
## [0.5.0] - 2017-10-24
|
|
194
225
|
|
|
195
226
|
### Added
|
|
196
227
|
|
|
@@ -203,9 +234,9 @@ Factory[:user, **user_attributes]
|
|
|
203
234
|
|
|
204
235
|
- Depends on `rom-core` now (solnic)
|
|
205
236
|
|
|
206
|
-
[
|
|
237
|
+
[0.5.0]: https://github.com/rom-rb/rom-factory/compare/v0.4.0...v0.5.0
|
|
207
238
|
|
|
208
|
-
## 0.4.0 2017-03-03
|
|
239
|
+
## [0.4.0] - 2017-03-03
|
|
209
240
|
|
|
210
241
|
improves internals.
|
|
211
242
|
|
|
@@ -224,3 +255,5 @@ improves internals.
|
|
|
224
255
|
- `Rom::Factory::Config.configure` was replaced with `ROM::Factory.configure` (solnic)
|
|
225
256
|
- Global factory config and builders are gone (solnic)
|
|
226
257
|
- Structs are now based on dry-struct (solnic)
|
|
258
|
+
|
|
259
|
+
[0.4.0]: https://github.com/rom-rb/rom-factory/tree/v0.4.0
|
data/LICENSE
CHANGED
data/README.md
CHANGED
|
@@ -1,29 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
[actions]: https://github.com/rom-rb/rom-factory/actions
|
|
3
|
-
[codacy]: https://www.codacy.com/gh/rom-rb/rom-factory
|
|
4
|
-
[chat]: https://rom-rb.zulipchat.com
|
|
5
|
-
[inchpages]: http://inch-ci.org/github/rom-rb/rom-factory
|
|
1
|
+
<!--- This file is synced from hanakai-rb/repo-sync -->
|
|
6
2
|
|
|
7
|
-
|
|
3
|
+
[actions]: https://github.com/hanakai-rb/rom-factory/actions
|
|
4
|
+
[chat]: https://discord.gg/naQApPAsZB
|
|
5
|
+
[forum]: https://discourse.hanakai.org
|
|
6
|
+
[rubygem]: https://rubygems.org/gems/rom-factory
|
|
8
7
|
|
|
9
|
-
[][
|
|
10
|
-
[][actions]
|
|
11
|
-
[][codacy]
|
|
12
|
-
[][codacy]
|
|
13
|
-
[][inchpages]
|
|
8
|
+
# ROM Factory [][rubygem] [][actions]
|
|
14
9
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
* [User documentation](https://rom-rb.org/learn/factory)
|
|
18
|
-
* [API documentation](https://rubydoc.info/gems/rom-factory)
|
|
10
|
+
[][forum]
|
|
11
|
+
[][chat]
|
|
19
12
|
|
|
20
|
-
##
|
|
13
|
+
## Links
|
|
21
14
|
|
|
22
|
-
|
|
15
|
+
- [User documentation](https://hanakai.org/learn/rom/factories)
|
|
16
|
+
- [API documentation](http://rubydoc.info/gems/rom-factory)
|
|
23
17
|
|
|
24
|
-
* MRI >= `3.1`
|
|
25
|
-
* jruby >= `9.4` (not tested in CI)
|
|
26
18
|
|
|
27
19
|
## License
|
|
28
20
|
|
|
29
21
|
See `LICENSE` file.
|
|
22
|
+
|
|
@@ -1,205 +1,213 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module ROM
|
|
4
|
-
module
|
|
5
|
-
|
|
6
|
-
# rubocop:disable Style/OptionalArguments
|
|
7
|
-
module Association
|
|
8
|
-
class << self
|
|
9
|
-
def new(assoc, ...)
|
|
10
|
-
const_get(assoc.definition.type).new(assoc, ...)
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
3
|
+
module ROM
|
|
4
|
+
module Factory
|
|
5
|
+
module Attributes
|
|
14
6
|
# @api private
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
@builder_proc = builder
|
|
22
|
-
@traits = traits
|
|
23
|
-
@options = options
|
|
7
|
+
# rubocop:disable Style/OptionalArguments
|
|
8
|
+
module Association
|
|
9
|
+
class << self
|
|
10
|
+
def new(assoc, ...)
|
|
11
|
+
const_get(assoc.definition.type).new(assoc, ...)
|
|
12
|
+
end
|
|
24
13
|
end
|
|
25
14
|
|
|
26
15
|
# @api private
|
|
27
|
-
|
|
16
|
+
class Core
|
|
17
|
+
attr_reader :assoc, :options, :traits
|
|
28
18
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
end
|
|
19
|
+
def transient
|
|
20
|
+
false
|
|
21
|
+
end
|
|
33
22
|
|
|
34
|
-
|
|
35
|
-
|
|
23
|
+
# @api private
|
|
24
|
+
def initialize(assoc, builder, *traits, **options)
|
|
25
|
+
@assoc = assoc
|
|
26
|
+
@builder_proc = builder
|
|
27
|
+
@traits = traits
|
|
28
|
+
@options = options
|
|
29
|
+
end
|
|
36
30
|
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
# @api private
|
|
32
|
+
def through? = false
|
|
39
33
|
|
|
40
|
-
|
|
41
|
-
|
|
34
|
+
# @api private
|
|
35
|
+
def builder
|
|
36
|
+
@__builder__ ||= @builder_proc.call
|
|
37
|
+
end
|
|
42
38
|
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
# @api private
|
|
40
|
+
def name = assoc.key
|
|
45
41
|
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
# @api private
|
|
43
|
+
def dependency?(*) = false
|
|
48
44
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
end
|
|
45
|
+
# @api private
|
|
46
|
+
def value? = false
|
|
52
47
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
# @api private
|
|
56
|
-
# rubocop:disable Metrics/AbcSize
|
|
57
|
-
def call(attrs, persist: true)
|
|
58
|
-
return if attrs.key?(name) && attrs[name].nil?
|
|
59
|
-
|
|
60
|
-
assoc_data = attrs.fetch(name, EMPTY_HASH)
|
|
61
|
-
|
|
62
|
-
if assoc_data.is_a?(::Hash) && assoc_data[assoc.target.primary_key] && !attrs[foreign_key]
|
|
63
|
-
assoc.associate(attrs, attrs[name])
|
|
64
|
-
elsif assoc_data.is_a?(::ROM::Struct)
|
|
65
|
-
assoc.associate(attrs, assoc_data)
|
|
66
|
-
else
|
|
67
|
-
parent =
|
|
68
|
-
if persist && !attrs[foreign_key]
|
|
69
|
-
builder.persistable.create(*parent_traits, **assoc_data)
|
|
70
|
-
else
|
|
71
|
-
builder.struct(
|
|
72
|
-
*parent_traits,
|
|
73
|
-
**assoc_data, assoc.target.primary_key => attrs[foreign_key]
|
|
74
|
-
)
|
|
75
|
-
end
|
|
48
|
+
# @api private
|
|
49
|
+
def factories = builder.factories
|
|
76
50
|
|
|
77
|
-
|
|
51
|
+
# @api private
|
|
52
|
+
def foreign_key = assoc.foreign_key
|
|
78
53
|
|
|
79
|
-
|
|
80
|
-
|
|
54
|
+
# @api private
|
|
55
|
+
def count = options.fetch(:count, 1)
|
|
81
56
|
end
|
|
82
|
-
# rubocop:enable Metrics/AbcSize
|
|
83
|
-
|
|
84
|
-
private
|
|
85
57
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
58
|
+
# @api private
|
|
59
|
+
class ManyToOne < Core
|
|
60
|
+
# @api private
|
|
61
|
+
# rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
|
|
62
|
+
def call(attrs, persist: true)
|
|
63
|
+
return if attrs.key?(name) && attrs[name].nil?
|
|
64
|
+
|
|
65
|
+
assoc_data = attrs.fetch(name, EMPTY_HASH)
|
|
66
|
+
|
|
67
|
+
if assoc_data.is_a?(::Hash) && assoc_data[assoc.target.primary_key] && !attrs[foreign_key]
|
|
68
|
+
assoc.associate(attrs, attrs[name])
|
|
69
|
+
elsif assoc_data.is_a?(::ROM::Struct)
|
|
70
|
+
assoc.associate(attrs, assoc_data)
|
|
90
71
|
else
|
|
91
|
-
|
|
72
|
+
parent =
|
|
73
|
+
if persist && !attrs[foreign_key]
|
|
74
|
+
builder.persistable.create(*parent_traits, **assoc_data)
|
|
75
|
+
else
|
|
76
|
+
builder.struct(
|
|
77
|
+
*parent_traits,
|
|
78
|
+
**assoc_data, assoc.target.primary_key => attrs[foreign_key]
|
|
79
|
+
)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
tuple = {name => parent}
|
|
83
|
+
|
|
84
|
+
assoc.associate(tuple, parent)
|
|
92
85
|
end
|
|
86
|
+
end
|
|
87
|
+
# rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity
|
|
88
|
+
|
|
89
|
+
private
|
|
90
|
+
|
|
91
|
+
def parent_traits
|
|
92
|
+
@parent_traits ||=
|
|
93
|
+
if assoc.target.associations.key?(assoc.source.name)
|
|
94
|
+
traits + [{assoc.target.associations[assoc.source.name].key => false}]
|
|
95
|
+
else
|
|
96
|
+
traits
|
|
97
|
+
end
|
|
98
|
+
end
|
|
93
99
|
end
|
|
94
|
-
end
|
|
95
100
|
|
|
96
|
-
# @api private
|
|
97
|
-
class OneToMany < Core
|
|
98
101
|
# @api private
|
|
99
|
-
|
|
100
|
-
|
|
102
|
+
class OneToMany < Core
|
|
103
|
+
# @api private
|
|
104
|
+
def call(attrs = EMPTY_HASH, parent, persist: true)
|
|
105
|
+
return if attrs.key?(name)
|
|
101
106
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
107
|
+
structs = ::Array.new(count).map do
|
|
108
|
+
# hash which contains the foreign key info, i.e: { user_id: 1 }
|
|
109
|
+
association_hash = assoc.associate(attrs, parent)
|
|
105
110
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
111
|
+
if persist
|
|
112
|
+
builder.persistable.create(*traits, **association_hash)
|
|
113
|
+
else
|
|
114
|
+
builder.struct(*traits, **attrs, **association_hash)
|
|
115
|
+
end
|
|
110
116
|
end
|
|
117
|
+
|
|
118
|
+
{name => structs}
|
|
111
119
|
end
|
|
112
120
|
|
|
113
|
-
|
|
121
|
+
# @api private
|
|
122
|
+
def dependency?(rel) = assoc.source == rel
|
|
114
123
|
end
|
|
115
124
|
|
|
116
125
|
# @api private
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
# @api private
|
|
123
|
-
def call(attrs = EMPTY_HASH, parent, persist: true)
|
|
124
|
-
# do not associate if count is 0
|
|
125
|
-
return {name => nil} if count.zero?
|
|
126
|
+
class OneToOne < OneToMany
|
|
127
|
+
# @api private
|
|
128
|
+
def call(attrs = EMPTY_HASH, parent, persist: true)
|
|
129
|
+
# do not associate if count is 0
|
|
130
|
+
return {name => nil} if count.zero?
|
|
126
131
|
|
|
127
|
-
|
|
132
|
+
return if attrs.key?(name)
|
|
128
133
|
|
|
129
|
-
|
|
134
|
+
association_hash = assoc.associate(attrs, parent)
|
|
130
135
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
136
|
+
struct =
|
|
137
|
+
if persist
|
|
138
|
+
builder.persistable.create(*traits, **association_hash)
|
|
139
|
+
else
|
|
140
|
+
belongs_to_name = ::ROM::Inflector.singularize(assoc.source_alias)
|
|
141
|
+
belongs_to_associations = {belongs_to_name.to_sym => parent}
|
|
142
|
+
final_attrs = attrs.merge(association_hash).merge(belongs_to_associations)
|
|
143
|
+
builder.struct(*traits, **final_attrs)
|
|
144
|
+
end
|
|
140
145
|
|
|
141
|
-
|
|
146
|
+
{name => struct}
|
|
147
|
+
end
|
|
142
148
|
end
|
|
143
|
-
end
|
|
144
149
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
150
|
+
class ManyToMany < Core
|
|
151
|
+
# rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
|
|
152
|
+
def call(attrs = EMPTY_HASH, parent, persist: true)
|
|
153
|
+
return if attrs.key?(name)
|
|
148
154
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
155
|
+
structs = count.times.map do
|
|
156
|
+
if persist && attrs[tpk]
|
|
157
|
+
attrs
|
|
158
|
+
elsif persist
|
|
159
|
+
builder.persistable.create(*traits, **attrs)
|
|
160
|
+
else
|
|
161
|
+
builder.struct(*traits, **attrs)
|
|
162
|
+
end
|
|
156
163
|
end
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
# Delegate to through factory if it exists
|
|
160
|
-
if persist
|
|
161
|
-
if through_factory?
|
|
162
|
-
structs.each do |child|
|
|
163
|
-
through_attrs = {
|
|
164
|
-
::ROM::Inflector.singularize(assoc.source.name.key).to_sym => parent,
|
|
165
|
-
assoc.through.assoc_name => child
|
|
166
|
-
}
|
|
167
164
|
|
|
168
|
-
|
|
165
|
+
# Delegate to through factory if it exists
|
|
166
|
+
if persist
|
|
167
|
+
if through_factory?
|
|
168
|
+
structs.each do |child|
|
|
169
|
+
through_attrs = {
|
|
170
|
+
::ROM::Inflector.singularize(assoc.source.name.key).to_sym => parent,
|
|
171
|
+
assoc.through.assoc_name => child
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
factories[through_factory_name, **through_attrs]
|
|
175
|
+
end
|
|
176
|
+
else
|
|
177
|
+
assoc.persist([parent], structs)
|
|
169
178
|
end
|
|
179
|
+
|
|
180
|
+
{name => result(structs)}
|
|
170
181
|
else
|
|
171
|
-
|
|
182
|
+
result(structs)
|
|
172
183
|
end
|
|
173
|
-
|
|
174
|
-
{name => result(structs)}
|
|
175
|
-
else
|
|
176
|
-
result(structs)
|
|
177
184
|
end
|
|
178
|
-
|
|
185
|
+
# rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity
|
|
179
186
|
|
|
180
|
-
|
|
187
|
+
def result(structs) = {name => structs}
|
|
181
188
|
|
|
182
|
-
|
|
189
|
+
def dependency?(rel) = assoc.source == rel
|
|
183
190
|
|
|
184
|
-
|
|
191
|
+
def through? = true
|
|
185
192
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
193
|
+
def through_factory?
|
|
194
|
+
factories.registry.key?(through_factory_name)
|
|
195
|
+
end
|
|
189
196
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
197
|
+
def through_factory_name
|
|
198
|
+
::ROM::Inflector.singularize(assoc.definition.through.source).to_sym
|
|
199
|
+
end
|
|
193
200
|
|
|
194
|
-
|
|
201
|
+
private
|
|
195
202
|
|
|
196
|
-
|
|
197
|
-
|
|
203
|
+
def tpk = assoc.target.primary_key
|
|
204
|
+
end
|
|
198
205
|
|
|
199
|
-
|
|
200
|
-
|
|
206
|
+
class OneToOneThrough < ManyToMany
|
|
207
|
+
def result(structs) = {name => structs[0]}
|
|
208
|
+
end
|
|
201
209
|
end
|
|
202
210
|
end
|
|
211
|
+
# rubocop:enable Style/OptionalArguments
|
|
203
212
|
end
|
|
204
|
-
# rubocop:enable Style/OptionalArguments
|
|
205
213
|
end
|