rom-factory 0.10.2 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.devtools/templates/changelog.erb +3 -0
- data/.devtools/templates/release.erb +36 -0
- data/.github/FUNDING.yml +1 -0
- data/.github/ISSUE_TEMPLATE/{---bug-report.md → bug-report.md} +6 -10
- data/.github/ISSUE_TEMPLATE/config.yml +5 -0
- data/.github/SUPPORT.md +3 -0
- data/.github/workflows/ci.yml +17 -25
- data/.github/workflows/docsite.yml +6 -6
- data/.github/workflows/rubocop.yml +46 -0
- data/.github/workflows/sync_configs.yml +7 -13
- data/.repobot.yml +24 -0
- data/.rubocop.yml +135 -16
- data/CHANGELOG.md +64 -0
- data/CODEOWNERS +1 -0
- data/CONTRIBUTING.md +3 -3
- data/Gemfile +20 -19
- data/Gemfile.devtools +6 -5
- data/LICENSE +1 -1
- data/README.md +3 -3
- data/Rakefile +1 -1
- data/benchmarks/basic.rb +10 -10
- data/changelog.yml +35 -0
- data/docsite/source/index.html.md +162 -1
- data/lib/rom/factory/attribute_registry.rb +6 -2
- data/lib/rom/factory/attributes/association.rb +127 -29
- data/lib/rom/factory/attributes/callable.rb +1 -1
- data/lib/rom/factory/attributes/value.rb +1 -1
- data/lib/rom/factory/attributes.rb +4 -6
- data/lib/rom/factory/builder/persistable.rb +21 -6
- data/lib/rom/factory/builder.rb +17 -19
- data/lib/rom/factory/constants.rb +1 -1
- data/lib/rom/factory/dsl.rb +43 -25
- data/lib/rom/factory/factories.rb +13 -15
- data/lib/rom/factory/registry.rb +2 -2
- data/lib/rom/factory/sequences.rb +4 -3
- data/lib/rom/factory/tuple_evaluator.rb +92 -43
- data/lib/rom/factory/version.rb +1 -1
- data/lib/rom/factory.rb +8 -5
- data/lib/rom-factory.rb +1 -1
- data/project.yml +1 -0
- data/rom-factory.gemspec +9 -10
- metadata +40 -26
- data/.github/ISSUE_TEMPLATE/----please-don-t-ask-for-support-via-issues.md +0 -10
- data/.github/ISSUE_TEMPLATE/----please-don-t-report-feature-requests-via-issues.md +0 -10
- data/.github/ISSUE_TEMPLATE/---a-detailed-bug-report.md +0 -30
- data/.github/ISSUE_TEMPLATE/---feature-request.md +0 -18
- data/.github/workflows/custom/ci.yml +0 -26
- data/Appraisals +0 -9
- data/LICENSE.txt +0 -21
data/Gemfile
CHANGED
@@ -1,38 +1,39 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
source
|
3
|
+
source "https://rubygems.org"
|
4
4
|
|
5
5
|
gemspec
|
6
6
|
|
7
|
-
eval_gemfile
|
7
|
+
eval_gemfile "Gemfile.devtools"
|
8
8
|
|
9
|
-
gem
|
9
|
+
gem "faker", "~> 3.0"
|
10
10
|
|
11
|
-
gem
|
12
|
-
gem 'rspec', '~> 3.0'
|
11
|
+
gem "rspec", "~> 3.0"
|
13
12
|
|
14
|
-
|
15
|
-
gem
|
13
|
+
git "https://github.com/rom-rb/rom.git", branch: "release-5.3" do
|
14
|
+
gem "rom-core"
|
15
|
+
gem "rom-changeset"
|
16
|
+
gem "rom-repository"
|
17
|
+
gem "rom"
|
16
18
|
end
|
17
19
|
|
18
20
|
group :test do
|
19
|
-
gem
|
20
|
-
gem
|
21
|
-
gem
|
22
|
-
gem 'pry', '~> 0.12.0', '<= 0.13'
|
21
|
+
gem "pry"
|
22
|
+
gem "pry-byebug", "~> 3.8", platforms: :ruby
|
23
|
+
gem "rom-sql", github: "rom-rb/rom-sql", branch: "release-3.6"
|
23
24
|
|
24
|
-
gem
|
25
|
-
gem
|
25
|
+
gem "jdbc-postgres", platforms: :jruby
|
26
|
+
gem "pg", "~> 1.5", platforms: :ruby
|
26
27
|
end
|
27
28
|
|
28
29
|
group :tools do
|
29
|
-
gem
|
30
|
-
gem
|
30
|
+
gem "byebug", platform: :mri
|
31
|
+
gem "redcarpet" # for yard
|
31
32
|
end
|
32
33
|
|
33
34
|
group :benchmarks do
|
34
|
-
gem
|
35
|
-
gem
|
36
|
-
gem
|
37
|
-
gem
|
35
|
+
gem "activerecord"
|
36
|
+
gem "benchmark-ips"
|
37
|
+
gem "fabrication"
|
38
|
+
gem "factory_bot"
|
38
39
|
end
|
data/Gemfile.devtools
CHANGED
@@ -2,18 +2,19 @@
|
|
2
2
|
|
3
3
|
# this file is managed by rom-rb/devtools project
|
4
4
|
|
5
|
+
gem "rake", ">= 12.3.3"
|
6
|
+
|
5
7
|
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
6
8
|
|
7
9
|
group :test do
|
8
|
-
|
9
|
-
gem "simplecov",
|
10
|
-
|
11
|
-
gem "codacy-coverage", require: false, platforms: :ruby
|
10
|
+
gem "simplecov", require: false, platforms: :ruby
|
11
|
+
gem "simplecov-cobertura", require: false, platforms: :ruby
|
12
|
+
gem "rexml", require: false
|
12
13
|
|
13
14
|
gem "warning" if RUBY_VERSION >= "2.4.0"
|
14
15
|
end
|
15
16
|
|
16
17
|
group :tools do
|
17
18
|
# this is the same version that we use on codacy
|
18
|
-
gem "rubocop", "
|
19
|
+
gem "rubocop", "1.26.1"
|
19
20
|
end
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -14,14 +14,14 @@
|
|
14
14
|
|
15
15
|
## Links
|
16
16
|
|
17
|
-
* [User documentation](
|
18
|
-
* [API documentation](
|
17
|
+
* [User documentation](https://rom-rb.org/learn/factory)
|
18
|
+
* [API documentation](https://rubydoc.info/gems/rom-factory)
|
19
19
|
|
20
20
|
## Supported Ruby versions
|
21
21
|
|
22
22
|
This library officially supports the following Ruby versions:
|
23
23
|
|
24
|
-
* MRI >= `2.
|
24
|
+
* MRI >= `2.5`
|
25
25
|
* jruby >= `9.2`
|
26
26
|
|
27
27
|
## License
|
data/Rakefile
CHANGED
data/benchmarks/basic.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
3
|
+
require "rom-factory"
|
4
|
+
require "rom-core"
|
5
|
+
require "active_record"
|
6
|
+
require "factory_bot"
|
7
|
+
require "fabrication"
|
8
|
+
require "benchmark/ips"
|
9
9
|
|
10
|
-
DATABASE_URL =
|
10
|
+
DATABASE_URL = "postgres://localhost/rom_factory_bench"
|
11
11
|
|
12
12
|
rom = ROM.container(:sql, DATABASE_URL) do |conf|
|
13
13
|
conf.default.connection.create_table?(:users) do
|
@@ -50,15 +50,15 @@ Fabricator(:user) do
|
|
50
50
|
end
|
51
51
|
|
52
52
|
Benchmark.ips do |x|
|
53
|
-
x.report(
|
53
|
+
x.report("rom-factory persisted struct") do
|
54
54
|
factory[:user]
|
55
55
|
end
|
56
56
|
|
57
|
-
x.report(
|
57
|
+
x.report("factory_bot") do
|
58
58
|
FactoryBot.create(:user)
|
59
59
|
end
|
60
60
|
|
61
|
-
x.report(
|
61
|
+
x.report("fabrication") do
|
62
62
|
Fabricate(:user)
|
63
63
|
end
|
64
64
|
|
data/changelog.yml
CHANGED
@@ -1,4 +1,39 @@
|
|
1
1
|
---
|
2
|
+
- version: 0.12.0
|
3
|
+
date: 2024-01-19
|
4
|
+
added:
|
5
|
+
- Support for many-to-many and one-to-one-through associations (via #86) (@solnic)
|
6
|
+
- Support for UUID as PKs in associations (via #87) (@solnic)
|
7
|
+
fixed:
|
8
|
+
- Relations without PKs should work too (via #87) (@solnic)
|
9
|
+
- Relations with PK values generated on the Ruby side should work in SQlite too (via #87) (@solnic)
|
10
|
+
- version: 0.11.0
|
11
|
+
date: 2022-11-11
|
12
|
+
added:
|
13
|
+
- Support for one-to-one associations (@ianks)
|
14
|
+
- "[internal] cache for Faker constants (@flash-gordon)"
|
15
|
+
changed:
|
16
|
+
- |
|
17
|
+
[BREAKING] attributes are always passed as keywords (@alassek)
|
18
|
+
This may affect your code in places where attributes are passed as hashes.
|
19
|
+
Places like
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
user_attributes = { name: 'Jane' }
|
23
|
+
Factory[:user, user_attributes]
|
24
|
+
|
25
|
+
```
|
26
|
+
|
27
|
+
must be updated to
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
user_attributes = { name: 'Jane' }
|
31
|
+
Factory[:user, **user_attributes]
|
32
|
+
```
|
33
|
+
- "Upgraded to the latest versions of dry-rb dependencies, compatible with rom 5.3 (@flash-gordon)"
|
34
|
+
- Support for Faker 1.x was dropped (@alassek)
|
35
|
+
fixed:
|
36
|
+
- Support for plural Faker generators (@wuarmin)
|
2
37
|
- version: 0.10.2
|
3
38
|
date: "2020-04-05"
|
4
39
|
fixed:
|
@@ -5,4 +5,165 @@ chapter: Factory
|
|
5
5
|
|
6
6
|
# rom-factory
|
7
7
|
|
8
|
-
|
8
|
+
`rom-factory` provides a simple API for creating and persisting `ROM::Struct`'s. If you already know FactoryBot you'll definitely understand the concept.
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
First of all you need to define a ROM Container for Factory. For example if you are using `rspec`, you can add these lines to `spec_helper.rb`. Also you need to require here all files with Factories.
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
Factory = ROM::Factory.configure do |config|
|
16
|
+
config.rom = my_rom_container
|
17
|
+
end
|
18
|
+
|
19
|
+
Dir[File.dirname(__FILE__) + '/support/factories/*.rb'].each { |file| require file }
|
20
|
+
```
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
### Define factory
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
# 'spec/support/factories/users.rb'
|
28
|
+
|
29
|
+
Factory.define(:user) do |f|
|
30
|
+
f.name 'John'
|
31
|
+
f.age 42
|
32
|
+
end
|
33
|
+
```
|
34
|
+
#### Specify relations
|
35
|
+
|
36
|
+
You can specify ROM relation if you want. It'll be pluralized factory name by default.
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
Factory.define(:user, relation: :people) do |f|
|
40
|
+
f.name 'John'
|
41
|
+
f.age 42
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
#### Specify namespace for your structs
|
46
|
+
|
47
|
+
Struct `User` will be found in `MyApp::Entities` namespace
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
Factory.define(:user, struct_namespace: MyApp::Entities) do |f|
|
51
|
+
# ...
|
52
|
+
end
|
53
|
+
```
|
54
|
+
|
55
|
+
#### Sequences
|
56
|
+
|
57
|
+
You can use sequences for uniq fields
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
Factory.define(:user) do |f|
|
61
|
+
f.name 'John'
|
62
|
+
f.sequence(:email) { |n| "john#{n}@example.com" }
|
63
|
+
end
|
64
|
+
```
|
65
|
+
|
66
|
+
#### Timestamps
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
Factory.define(:user) do |f|
|
70
|
+
f.name 'John'
|
71
|
+
f.timestamps
|
72
|
+
# same as
|
73
|
+
# f.created_at { Time.now }
|
74
|
+
# f.updated_at { Time.now }
|
75
|
+
end
|
76
|
+
```
|
77
|
+
|
78
|
+
#### Associations
|
79
|
+
|
80
|
+
* belongs_to
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
Factory.define(:group) do |f|
|
84
|
+
f.name 'Admins'
|
85
|
+
end
|
86
|
+
|
87
|
+
Factory.define(:user) do |f|
|
88
|
+
f.name 'John'
|
89
|
+
f.association(:group)
|
90
|
+
end
|
91
|
+
```
|
92
|
+
|
93
|
+
* has_many
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
Factory.define(:group) do |f|
|
97
|
+
f.name 'Admins'
|
98
|
+
f.association(:user, count: 2)
|
99
|
+
end
|
100
|
+
|
101
|
+
Factory.define(:user) do |f|
|
102
|
+
f.name 'John'
|
103
|
+
end
|
104
|
+
```
|
105
|
+
|
106
|
+
#### Extend already existing factory
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
Factory.define(:user) do |f|
|
110
|
+
f.name 'John'
|
111
|
+
f.admin false
|
112
|
+
end
|
113
|
+
|
114
|
+
Factory.define(admin: :user) do |f|
|
115
|
+
f.admin true
|
116
|
+
end
|
117
|
+
|
118
|
+
# Factory.structs[:admin]
|
119
|
+
```
|
120
|
+
|
121
|
+
#### Traits
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
Factory.define(:user) do |f|
|
125
|
+
f.name 'John'
|
126
|
+
f.admin false
|
127
|
+
|
128
|
+
f.trait :with_age do |t|
|
129
|
+
t.age 42
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Factory.structs[:user, :with_age]
|
134
|
+
```
|
135
|
+
|
136
|
+
#### Build-in [Faker](https://github.com/faker-ruby/faker) objects
|
137
|
+
|
138
|
+
```ruby
|
139
|
+
Factory.define(:user) do |f|
|
140
|
+
f.email { fake(:internet, :email) }
|
141
|
+
end
|
142
|
+
```
|
143
|
+
|
144
|
+
#### Dependent attributes
|
145
|
+
|
146
|
+
Attributes can be based on the values of other attributes:
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
Factory.define(:user) do |f|
|
150
|
+
f.full_name { fake(:name) }
|
151
|
+
# Dependent attributes are inferred from the block parameter names:
|
152
|
+
f.login { |full_name| full_name.downcase.gsub(/\s+/, '_') }
|
153
|
+
# Works with sequences too:
|
154
|
+
f.sequence(:email) { |n, login| "#{login}-#{n}@example.com" }
|
155
|
+
end
|
156
|
+
```
|
157
|
+
|
158
|
+
### Build and persist objects
|
159
|
+
|
160
|
+
```ruby
|
161
|
+
# Create in-memory object
|
162
|
+
Factory.structs[:user]
|
163
|
+
|
164
|
+
# Persist struct in database
|
165
|
+
Factory[:user]
|
166
|
+
|
167
|
+
# Override attributes
|
168
|
+
Factory[:user, age: 24]
|
169
|
+
```
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "tsort"
|
4
4
|
|
5
5
|
module ROM
|
6
6
|
module Factory
|
@@ -47,7 +47,11 @@ module ROM
|
|
47
47
|
|
48
48
|
# @api private
|
49
49
|
def associations
|
50
|
-
self.class.new(elements.select { |e| e.
|
50
|
+
self.class.new(elements.select { |e| e.is_a?(Attributes::Association::Core) })
|
51
|
+
end
|
52
|
+
|
53
|
+
def reject(&block)
|
54
|
+
self.class.new(elements.reject(&block))
|
51
55
|
end
|
52
56
|
|
53
57
|
private
|
@@ -3,12 +3,12 @@
|
|
3
3
|
module ROM::Factory
|
4
4
|
module Attributes
|
5
5
|
# @api private
|
6
|
+
# rubocop:disable Style/OptionalArguments
|
6
7
|
module Association
|
7
8
|
class << self
|
8
|
-
def new(assoc, builder, *
|
9
|
-
const_get(assoc.definition.type).new(assoc, builder, *
|
9
|
+
def new(assoc, builder, *traits, **options)
|
10
|
+
const_get(assoc.definition.type).new(assoc, builder, *traits, **options)
|
10
11
|
end
|
11
|
-
ruby2_keywords(:new) if respond_to?(:ruby2_keywords, true)
|
12
12
|
end
|
13
13
|
|
14
14
|
# @api private
|
@@ -23,6 +23,11 @@ module ROM::Factory
|
|
23
23
|
@options = options
|
24
24
|
end
|
25
25
|
|
26
|
+
# @api private
|
27
|
+
def through?
|
28
|
+
false
|
29
|
+
end
|
30
|
+
|
26
31
|
# @api private
|
27
32
|
def builder
|
28
33
|
@__builder__ ||= @builder_proc.call
|
@@ -42,28 +47,62 @@ module ROM::Factory
|
|
42
47
|
def value?
|
43
48
|
false
|
44
49
|
end
|
50
|
+
|
51
|
+
# @api private
|
52
|
+
def factories
|
53
|
+
builder.factories
|
54
|
+
end
|
55
|
+
|
56
|
+
# @api private
|
57
|
+
def foreign_key
|
58
|
+
assoc.foreign_key
|
59
|
+
end
|
60
|
+
|
61
|
+
# @api private
|
62
|
+
def count
|
63
|
+
options.fetch(:count, 1)
|
64
|
+
end
|
45
65
|
end
|
46
66
|
|
47
67
|
# @api private
|
48
68
|
class ManyToOne < Core
|
49
69
|
# @api private
|
70
|
+
# rubocop:disable Metrics/AbcSize
|
50
71
|
def call(attrs, persist: true)
|
51
|
-
if attrs.key?(name) &&
|
72
|
+
return if attrs.key?(name) && attrs[name].nil?
|
73
|
+
|
74
|
+
assoc_data = attrs.fetch(name, EMPTY_HASH)
|
75
|
+
|
76
|
+
if assoc_data.is_a?(Hash) && assoc_data[assoc.target.primary_key] && !attrs[foreign_key]
|
52
77
|
assoc.associate(attrs, attrs[name])
|
53
|
-
elsif
|
54
|
-
|
55
|
-
|
78
|
+
elsif assoc_data.is_a?(ROM::Struct)
|
79
|
+
assoc.associate(attrs, assoc_data)
|
80
|
+
else
|
81
|
+
parent = if persist && !attrs[foreign_key]
|
82
|
+
builder.persistable.create(*parent_traits, **assoc_data)
|
56
83
|
else
|
57
|
-
builder.struct(
|
84
|
+
builder.struct(
|
85
|
+
*parent_traits,
|
86
|
+
**assoc_data.merge(assoc.target.primary_key => attrs[foreign_key])
|
87
|
+
)
|
58
88
|
end
|
59
|
-
|
60
|
-
|
89
|
+
|
90
|
+
tuple = {name => parent}
|
91
|
+
|
92
|
+
assoc.associate(tuple, parent)
|
61
93
|
end
|
62
94
|
end
|
95
|
+
# rubocop:enable Metrics/AbcSize
|
63
96
|
|
64
|
-
|
65
|
-
|
66
|
-
|
97
|
+
private
|
98
|
+
|
99
|
+
def parent_traits
|
100
|
+
@parent_traits ||=
|
101
|
+
if assoc.target.associations.key?(assoc.source.name)
|
102
|
+
traits + [assoc.target.associations[assoc.source.name].key => false]
|
103
|
+
else
|
104
|
+
traits
|
105
|
+
end
|
67
106
|
end
|
68
107
|
end
|
69
108
|
|
@@ -78,24 +117,19 @@ module ROM::Factory
|
|
78
117
|
association_hash = assoc.associate(attrs, parent)
|
79
118
|
|
80
119
|
if persist
|
81
|
-
builder.persistable.create(*traits, association_hash)
|
120
|
+
builder.persistable.create(*traits, **association_hash)
|
82
121
|
else
|
83
|
-
builder.struct(*traits, attrs
|
122
|
+
builder.struct(*traits, **attrs, **association_hash)
|
84
123
|
end
|
85
124
|
end
|
86
125
|
|
87
|
-
{
|
126
|
+
{name => structs}
|
88
127
|
end
|
89
128
|
|
90
129
|
# @api private
|
91
130
|
def dependency?(rel)
|
92
131
|
assoc.source == rel
|
93
132
|
end
|
94
|
-
|
95
|
-
# @api private
|
96
|
-
def count
|
97
|
-
options.fetch(:count)
|
98
|
-
end
|
99
133
|
end
|
100
134
|
|
101
135
|
# @api private
|
@@ -103,29 +137,93 @@ module ROM::Factory
|
|
103
137
|
# @api private
|
104
138
|
def call(attrs = EMPTY_HASH, parent, persist: true)
|
105
139
|
# do not associate if count is 0
|
106
|
-
return {
|
140
|
+
return {name => nil} if count.zero?
|
107
141
|
|
108
142
|
return if attrs.key?(name)
|
109
143
|
|
110
144
|
association_hash = assoc.associate(attrs, parent)
|
111
145
|
|
112
146
|
struct = if persist
|
113
|
-
builder.persistable.create(*traits, association_hash)
|
147
|
+
builder.persistable.create(*traits, **association_hash)
|
114
148
|
else
|
115
149
|
belongs_to_name = Dry::Core::Inflector.singularize(assoc.source_alias)
|
116
|
-
belongs_to_associations = {
|
150
|
+
belongs_to_associations = {belongs_to_name.to_sym => parent}
|
117
151
|
final_attrs = attrs.merge(association_hash).merge(belongs_to_associations)
|
118
|
-
builder.struct(*traits, final_attrs)
|
152
|
+
builder.struct(*traits, **final_attrs)
|
119
153
|
end
|
120
154
|
|
121
|
-
{
|
155
|
+
{name => struct}
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
class ManyToMany < Core
|
160
|
+
def call(attrs = EMPTY_HASH, parent, persist: true)
|
161
|
+
return if attrs.key?(name)
|
162
|
+
|
163
|
+
structs = count.times.map do
|
164
|
+
if persist && attrs[tpk]
|
165
|
+
attrs
|
166
|
+
elsif persist
|
167
|
+
builder.persistable.create(*traits, **attrs)
|
168
|
+
else
|
169
|
+
builder.struct(*traits, **attrs)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
# Delegate to through factory if it exists
|
174
|
+
if persist
|
175
|
+
if through_factory?
|
176
|
+
structs.each do |child|
|
177
|
+
through_attrs = {
|
178
|
+
Dry::Core::Inflector.singularize(assoc.source.name.key).to_sym => parent,
|
179
|
+
assoc.through.assoc_name => child
|
180
|
+
}
|
181
|
+
|
182
|
+
factories[through_factory_name, **through_attrs]
|
183
|
+
end
|
184
|
+
else
|
185
|
+
assoc.persist([parent], structs)
|
186
|
+
end
|
187
|
+
|
188
|
+
{name => result(structs)}
|
189
|
+
else
|
190
|
+
result(structs)
|
191
|
+
end
|
122
192
|
end
|
123
193
|
|
124
|
-
|
125
|
-
|
126
|
-
|
194
|
+
def result(structs)
|
195
|
+
{name => structs}
|
196
|
+
end
|
197
|
+
|
198
|
+
def dependency?(rel)
|
199
|
+
assoc.source == rel
|
200
|
+
end
|
201
|
+
|
202
|
+
def through?
|
203
|
+
true
|
204
|
+
end
|
205
|
+
|
206
|
+
def through_factory?
|
207
|
+
factories.registry.key?(through_factory_name)
|
208
|
+
end
|
209
|
+
|
210
|
+
def through_factory_name
|
211
|
+
ROM::Inflector.singularize(assoc.definition.through.source).to_sym
|
212
|
+
end
|
213
|
+
|
214
|
+
private
|
215
|
+
|
216
|
+
def tpk
|
217
|
+
assoc.target.primary_key
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
class OneToOneThrough < ManyToMany
|
222
|
+
def result(structs)
|
223
|
+
{name => structs[0]}
|
127
224
|
end
|
128
225
|
end
|
129
226
|
end
|
130
227
|
end
|
228
|
+
# rubocop:enable Style/OptionalArguments
|
131
229
|
end
|
@@ -1,14 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'dry/core/constants'
|
4
|
-
|
5
3
|
module ROM
|
6
4
|
module Factory
|
7
5
|
include Dry::Core::Constants
|
8
6
|
end
|
9
7
|
end
|
10
8
|
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
9
|
+
require "rom/factory/attributes/value"
|
10
|
+
require "rom/factory/attributes/callable"
|
11
|
+
require "rom/factory/attributes/sequence"
|
12
|
+
require "rom/factory/attributes/association"
|