adjustable_schema 0.6.0 → 0.7.1
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/README.md +42 -6
- data/db/migrate/01_create_adjustable_schema_relationship_tables.rb +11 -4
- data/lib/adjustable_schema/active_record/association/naming.rb +9 -4
- data/lib/adjustable_schema/active_record/association.rb +32 -4
- data/lib/adjustable_schema/config.rb +2 -2
- data/lib/adjustable_schema/engine.rb +9 -6
- data/lib/adjustable_schema/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a26450a562fbcde4b87abd3a84e85f577d3c1a7c9f8ecfdf22b79728875f1e6
|
4
|
+
data.tar.gz: b2cda5f212ae129a97b92a80440f8e053af2c44d5c54676e2358da3230cb987a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1bf5d1bcef25e17cdbfc7de6d1f4f0278571169e9416d96fa4542ae654ea236184b39fa162938870d085a5afc496beac98e8a6a48ad311e69a277a97eb2f01d8
|
7
|
+
data.tar.gz: '099e2973293293635d6a1a1cda5a3105363e5c42dedc14cc30f07fc967870b6586da29dd4443e2ab37ee7b93059e063e538a8f3c39bc98308354342f5398a3bb'
|
data/README.md
CHANGED
@@ -56,10 +56,12 @@ book.editor_people
|
|
56
56
|
|
57
57
|
#### Special cases
|
58
58
|
|
59
|
-
|
59
|
+
##### "Actor-like" models
|
60
|
+
|
61
|
+
In case you have set up relationships with `User` model you'll get a slightly different naming:
|
60
62
|
|
61
63
|
``` ruby
|
62
|
-
AdjustableSchema::Relationship.seed! User => Book, %w[author editor]
|
64
|
+
AdjustableSchema::Relationship.seed! User => Book, roles: %w[author editor]
|
63
65
|
```
|
64
66
|
|
65
67
|
``` ruby
|
@@ -71,11 +73,42 @@ book.editors
|
|
71
73
|
The list of models to be handled this way can be set with `actor_model_names` configuration parameter.
|
72
74
|
It includes `User` by default.
|
73
75
|
|
74
|
-
|
76
|
+
##### Self-referencing models
|
77
|
+
|
78
|
+
You may want to set up self-targeted relationships:
|
79
|
+
|
80
|
+
``` ruby
|
81
|
+
AdjustableSchema::Relationship.seed! Person, roles: %w[friend]
|
82
|
+
```
|
83
|
+
|
84
|
+
In this case you'll get these associations:
|
85
|
+
|
86
|
+
``` ruby
|
87
|
+
person.parents
|
88
|
+
person.children # for all the children
|
89
|
+
person.people # for "roleless" children, not friends
|
90
|
+
person.friends
|
91
|
+
person.friended_people
|
92
|
+
```
|
93
|
+
|
94
|
+
If you prefer a different naming over `parents` & `children`, you can configure it like this:
|
75
95
|
|
76
|
-
|
96
|
+
```ruby
|
97
|
+
AdjustableSchema::Engine.configure do
|
98
|
+
config.names[:associations][:source][:self] = :effect
|
99
|
+
config.names[:associations][:target][:self] = :cause
|
100
|
+
end
|
101
|
+
```
|
102
|
+
|
103
|
+
Thus, for the self-referenced `Event`s, you'll get:
|
104
|
+
|
105
|
+
``` ruby
|
106
|
+
event.causes
|
107
|
+
event.effects
|
108
|
+
```
|
77
109
|
|
78
110
|
## Installation
|
111
|
+
|
79
112
|
Add this line to your application's Gemfile:
|
80
113
|
|
81
114
|
```ruby
|
@@ -83,13 +116,15 @@ gem "adjustable_schema"
|
|
83
116
|
```
|
84
117
|
|
85
118
|
And then execute:
|
119
|
+
|
86
120
|
```bash
|
87
|
-
|
121
|
+
bundle
|
88
122
|
```
|
89
123
|
|
90
124
|
Or install it yourself as:
|
125
|
+
|
91
126
|
```bash
|
92
|
-
|
127
|
+
gem install adjustable_schema
|
93
128
|
```
|
94
129
|
|
95
130
|
## Contributing
|
@@ -101,4 +136,5 @@ $ gem install adjustable_schema
|
|
101
136
|
5. Create new Pull Request
|
102
137
|
|
103
138
|
## License
|
139
|
+
|
104
140
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -4,7 +4,7 @@ class CreateAdjustableSchemaRelationshipTables < ActiveRecord::Migration[7.1]
|
|
4
4
|
primary_key_type, foreign_key_type = primary_and_foreign_key_types
|
5
5
|
|
6
6
|
create_table :adjustable_schema_relationship_roles do |t|
|
7
|
-
t.string :name, index: { unique: true }
|
7
|
+
t.string :name, null: false, index: { unique: true }
|
8
8
|
|
9
9
|
t.timestamps
|
10
10
|
end
|
@@ -17,13 +17,20 @@ class CreateAdjustableSchemaRelationshipTables < ActiveRecord::Migration[7.1]
|
|
17
17
|
|
18
18
|
t.timestamps
|
19
19
|
|
20
|
-
|
20
|
+
%i[
|
21
21
|
source_id source_type
|
22
22
|
target_id target_type
|
23
23
|
role_id
|
24
24
|
].tap { |columns|
|
25
|
-
|
26
|
-
|
25
|
+
columns.reject! { _1.ends_with? '_type' } if foreign_key_type == :uuid # OPTIMIZATION: IDs are unique
|
26
|
+
|
27
|
+
# NULLS are DISTINCT by default.
|
28
|
+
# One can use `ADD CONSTRAINT … UNIQUE NULLS NOT DISTINCT (…)` instead
|
29
|
+
t.index columns,
|
30
|
+
unique: true, where: 'role_id IS NOT NULL', name: :index_adjustable_schema_relationships_uniqueness_with_role
|
31
|
+
t.index columns.excluding(:role_id),
|
32
|
+
unique: true, where: 'role_id IS NULL', name: :index_adjustable_schema_relationships_uniqueness_without_role
|
33
|
+
}
|
27
34
|
end
|
28
35
|
end
|
29
36
|
|
@@ -9,7 +9,9 @@ module AdjustableSchema
|
|
9
9
|
module Inflections
|
10
10
|
refine String do
|
11
11
|
def passivize
|
12
|
-
|
12
|
+
self
|
13
|
+
.sub(/(author)$/, '\\2ed')
|
14
|
+
.sub(/(e*|ed|ing|[eo]r|ant|(t)ion)$/, '\\2ed')
|
13
15
|
end
|
14
16
|
end
|
15
17
|
end
|
@@ -36,7 +38,7 @@ module AdjustableSchema
|
|
36
38
|
private
|
37
39
|
|
38
40
|
memoize def name_with_role
|
39
|
-
if
|
41
|
+
if recursive?
|
40
42
|
{
|
41
43
|
source: role.name,
|
42
44
|
target: "#{role.name.passivize}_#{target_name}",
|
@@ -50,13 +52,16 @@ module AdjustableSchema
|
|
50
52
|
end
|
51
53
|
|
52
54
|
memoize def name_without_role
|
53
|
-
if
|
55
|
+
if recursive?
|
54
56
|
Config.association_directions
|
55
|
-
.
|
57
|
+
.self[direction]
|
56
58
|
else
|
57
59
|
target_name
|
58
60
|
end
|
59
61
|
end
|
62
|
+
|
63
|
+
def name_for_any = :"#{name.to_s.singularize.passivize}"
|
64
|
+
def name_for_none = :"#{name.to_s.singularize}less"
|
60
65
|
end
|
61
66
|
end
|
62
67
|
end
|
@@ -15,19 +15,24 @@ module AdjustableSchema
|
|
15
15
|
class_name: target.name
|
16
16
|
}) do
|
17
17
|
include Scopes
|
18
|
-
include Scopes::Recursive if association.
|
18
|
+
include Scopes::Recursive if association.recursive?
|
19
19
|
end
|
20
20
|
|
21
|
+
define_scopes
|
22
|
+
define_methods
|
23
|
+
|
21
24
|
unless role
|
22
|
-
|
23
|
-
|
25
|
+
# HACK: using `try` to overcome a Rails bug
|
26
|
+
# (see https://github.com/rails/rails/issues/40109)
|
27
|
+
has_many target_name.tableize.to_sym, -> { try :roleless }, **options if
|
28
|
+
recursive?
|
24
29
|
|
25
30
|
define_role_methods
|
26
31
|
end
|
27
32
|
end
|
28
33
|
end
|
29
34
|
|
30
|
-
def
|
35
|
+
def recursive? = target == owner
|
31
36
|
|
32
37
|
private
|
33
38
|
|
@@ -40,6 +45,29 @@ module AdjustableSchema
|
|
40
45
|
end
|
41
46
|
end
|
42
47
|
|
48
|
+
def define_scopes
|
49
|
+
name = relationships_name
|
50
|
+
|
51
|
+
{
|
52
|
+
name_for_any => -> { where.associated name },
|
53
|
+
name_for_none => -> { where.missing name },
|
54
|
+
}
|
55
|
+
.reject { owner.singleton_class.method_defined? _1 }
|
56
|
+
.each { owner.scope _1, _2 }
|
57
|
+
end
|
58
|
+
|
59
|
+
def define_methods
|
60
|
+
name = self.name
|
61
|
+
|
62
|
+
{
|
63
|
+
name_for_any => -> { send(name).any? },
|
64
|
+
name_for_none => -> { send(name).none? },
|
65
|
+
}
|
66
|
+
.transform_keys {"#{_1}?" }
|
67
|
+
.reject { owner.method_defined? _1 }
|
68
|
+
.each { owner.define_method _1, &_2 }
|
69
|
+
end
|
70
|
+
|
43
71
|
def define_role_methods
|
44
72
|
name = self.name
|
45
73
|
|
@@ -19,11 +19,11 @@ module AdjustableSchema
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
def
|
22
|
+
def self = config :self
|
23
23
|
|
24
24
|
def recursive
|
25
25
|
config.values.to_h do
|
26
|
-
[ _1[:
|
26
|
+
[ _1[:self].to_s.pluralize.to_sym, _1[:recursive].to_sym ]
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -7,16 +7,19 @@ module AdjustableSchema
|
|
7
7
|
config.names = {
|
8
8
|
associations: {
|
9
9
|
source: {
|
10
|
-
shortcut:
|
11
|
-
|
12
|
-
recursive:
|
10
|
+
shortcut: :of,
|
11
|
+
self: :child,
|
12
|
+
recursive: :descendants,
|
13
13
|
},
|
14
14
|
target: {
|
15
|
-
shortcut:
|
16
|
-
|
17
|
-
recursive:
|
15
|
+
shortcut: :to,
|
16
|
+
self: :parent,
|
17
|
+
recursive: :ancestors,
|
18
18
|
},
|
19
19
|
},
|
20
20
|
}
|
21
|
+
|
22
|
+
config.active_record
|
23
|
+
.automatically_invert_plural_associations = true
|
21
24
|
end
|
22
25
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: adjustable_schema
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Senko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-03-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -111,7 +111,7 @@ licenses:
|
|
111
111
|
metadata:
|
112
112
|
homepage_uri: https://github.com/Alexander-Senko/adjustable_schema
|
113
113
|
source_code_uri: https://github.com/Alexander-Senko/adjustable_schema
|
114
|
-
changelog_uri: https://github.com/Alexander-Senko/adjustable_schema/blob/v0.
|
114
|
+
changelog_uri: https://github.com/Alexander-Senko/adjustable_schema/blob/v0.7.1/CHANGELOG.md
|
115
115
|
post_install_message:
|
116
116
|
rdoc_options: []
|
117
117
|
require_paths:
|
@@ -127,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
127
|
- !ruby/object:Gem::Version
|
128
128
|
version: '0'
|
129
129
|
requirements: []
|
130
|
-
rubygems_version: 3.5.
|
130
|
+
rubygems_version: 3.5.6
|
131
131
|
signing_key:
|
132
132
|
specification_version: 4
|
133
133
|
summary: Adjustable data schemas for Rails
|