adjustable_schema 0.7.2 → 0.8.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 +108 -0
- data/README.md +2 -2
- data/app/models/adjustable_schema/relationship.rb +2 -2
- data/app/models/concerns/adjustable_schema/active_record/relationships.rb +1 -1
- data/db/migrate/01_create_adjustable_schema_relationship_tables.rb +1 -1
- data/lib/adjustable_schema/active_record/association/naming.rb +21 -7
- data/lib/adjustable_schema/active_record/association.rb +24 -4
- data/lib/adjustable_schema/config.rb +2 -2
- data/lib/adjustable_schema/version.rb +1 -1
- metadata +4 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e36fef6757e9e0803ad940f90a425ea0b25870c0720b0d338ed14970a35e339
|
4
|
+
data.tar.gz: a50db598919a729c33f607f107b1f78145d3fe262e00d0b7899dacb473ebc194
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 631771aa7ea4295ba2d886ab24a1e102b1ab50b9d3631ff467a3f46fd6f48a5bcd1f4ff2af62523510cc4c5d361852ef71dd183ca5846d20cf3a939ba25864f8
|
7
|
+
data.tar.gz: 57cd60293cb11377429fb2f808115301bb84f3a9c71372c7e0e5040bc8441e3ca62b244906d96785f1a34845c9542a1617107d7887dd01b9481b2b658ecae1d5
|
data/CHANGELOG.md
CHANGED
@@ -0,0 +1,108 @@
|
|
1
|
+
## [0.8.0] — 2024-11-08
|
2
|
+
|
3
|
+
### Changed
|
4
|
+
|
5
|
+
- Renamed checks for related records:
|
6
|
+
`<associat>ful` form is now used instead of a passive one (`<associat>ed`) to check for related records’ presence.
|
7
|
+
- `.<associat>ful` — scope records having associated ones.
|
8
|
+
- `#<associat>ful?` — are there any records associated?
|
9
|
+
- Naming: improved passive forms for words ending with `or`/`ant`/`ion`/`ment`/`ing`.
|
10
|
+
|
11
|
+
### Added
|
12
|
+
|
13
|
+
- Checks for related records’ presence on roleless recursive associations:
|
14
|
+
- `.<associat>ful` —
|
15
|
+
records having associated ones;
|
16
|
+
- `.<association>less` —
|
17
|
+
records not having associated ones;
|
18
|
+
- `#<associat>ful?` —
|
19
|
+
if there are records associated;
|
20
|
+
- `#<association>less?` —
|
21
|
+
if there are no records associated;
|
22
|
+
- `#intermediate?` —
|
23
|
+
whether is only one child record associated (_Is the node just a link between two other nodes like?_);
|
24
|
+
- `#branching?` —
|
25
|
+
whether are several child records associated.
|
26
|
+
|
27
|
+
### Fixed
|
28
|
+
|
29
|
+
- Naming: passive form for `author`.
|
30
|
+
|
31
|
+
|
32
|
+
## [0.7.2] — 2024-04-02
|
33
|
+
|
34
|
+
### Fixed
|
35
|
+
|
36
|
+
- `roleless` scope used to generate wrong queries.
|
37
|
+
|
38
|
+
|
39
|
+
## [0.7.1] — 2024-03-31
|
40
|
+
|
41
|
+
### Fixed
|
42
|
+
|
43
|
+
- DB constraints:
|
44
|
+
- `roles.name` is `NOT NULL`,
|
45
|
+
- `UNIQUE` constraints should treat `NULLS` as `NOT DISTINCT`.
|
46
|
+
- Roleless recursive associations used to fail on `joins`.
|
47
|
+
|
48
|
+
|
49
|
+
## [0.7.0] — 2024-02-25
|
50
|
+
|
51
|
+
### Changed
|
52
|
+
|
53
|
+
- Naming: improved passive forms a bit.
|
54
|
+
- Configuration: renamed `self_related` to `self`.
|
55
|
+
|
56
|
+
### Added
|
57
|
+
|
58
|
+
- Checks for related records’ presence:
|
59
|
+
- `.<associat>ed` —
|
60
|
+
records having associated ones;
|
61
|
+
- `.<association>less` —
|
62
|
+
records not having associated ones;
|
63
|
+
- `#<associat>ed?` —
|
64
|
+
if there are records associated;
|
65
|
+
- `#<association>less?` —
|
66
|
+
if there are no records associated.
|
67
|
+
- Documentation: self-targeted relationships in README.
|
68
|
+
|
69
|
+
### Fixed
|
70
|
+
|
71
|
+
- Documentation: examples in the README.
|
72
|
+
|
73
|
+
|
74
|
+
## [0.6.0] — 2024-02-20
|
75
|
+
|
76
|
+
### Changed
|
77
|
+
|
78
|
+
- Destroy orphaned relationships of an object on destroy.
|
79
|
+
- Symbolize configurable names used for associations, methods, etc.
|
80
|
+
- Raise `ArgumentError` for unknown names passed to the API.
|
81
|
+
|
82
|
+
### Added
|
83
|
+
|
84
|
+
- `Relationship[]` to filter relationships by related objects/classes.
|
85
|
+
- `Role[]` accepts `Hash`-like parameters to filter roles by relationships.
|
86
|
+
- Methods for related records:
|
87
|
+
- `related?` to check for related objects,
|
88
|
+
- `related` to fetch them,
|
89
|
+
- and the basic `relationships`.
|
90
|
+
- Recursive methods for related records:
|
91
|
+
- flat `ancestors` & `descendants` with distance,
|
92
|
+
- based on `recursive` association scope.
|
93
|
+
- `roleless` scope for related records without a role.
|
94
|
+
- A dedicated association for roleless children.
|
95
|
+
|
96
|
+
### Fixed
|
97
|
+
|
98
|
+
- Faulty scopes in role-based relationship associations.
|
99
|
+
- Naming for namespaced models, e.g., in Rails Engines.
|
100
|
+
|
101
|
+
|
102
|
+
## [0.5.0] — 2023-12-29
|
103
|
+
|
104
|
+
Refactored from [Rails Dynamic Associations](
|
105
|
+
https://github.com/Alexander-Senko/rails_dynamic_associations
|
106
|
+
).
|
107
|
+
|
108
|
+
Some experimental features are missing and can be found in the `api` branch.
|
data/README.md
CHANGED
@@ -75,7 +75,7 @@ It includes `User` by default.
|
|
75
75
|
|
76
76
|
##### Self-referencing models
|
77
77
|
|
78
|
-
You may want to set up
|
78
|
+
You may want to set up recursive relationships:
|
79
79
|
|
80
80
|
``` ruby
|
81
81
|
AdjustableSchema::Relationship.seed! Person, roles: %w[friend]
|
@@ -100,7 +100,7 @@ AdjustableSchema::Engine.configure do
|
|
100
100
|
end
|
101
101
|
```
|
102
102
|
|
103
|
-
Thus, for
|
103
|
+
Thus, for hierarchical `Event`s, you'll get:
|
104
104
|
|
105
105
|
``` ruby
|
106
106
|
event.causes
|
@@ -15,7 +15,7 @@ module AdjustableSchema
|
|
15
15
|
where association => object
|
16
16
|
when Class
|
17
17
|
where "#{association}_type" => object.ancestors
|
18
|
-
.
|
18
|
+
.grep(..object.base_class)
|
19
19
|
.map(&:name)
|
20
20
|
when ::ActiveRecord::Relation
|
21
21
|
send(method, object.klass)
|
@@ -100,7 +100,7 @@ module AdjustableSchema
|
|
100
100
|
end
|
101
101
|
end
|
102
102
|
in [ Class => source ]
|
103
|
-
seed! source, source, roles: #
|
103
|
+
seed! source, source, roles: # recursive
|
104
104
|
end
|
105
105
|
end
|
106
106
|
end
|
@@ -28,7 +28,7 @@ class CreateAdjustableSchemaRelationshipTables < ActiveRecord::Migration[7.1]
|
|
28
28
|
# One can use `ADD CONSTRAINT … UNIQUE NULLS NOT DISTINCT (…)` instead
|
29
29
|
t.index columns,
|
30
30
|
unique: true, where: 'role_id IS NOT NULL', name: :index_adjustable_schema_relationships_uniqueness_with_role
|
31
|
-
t.index columns.
|
31
|
+
t.index columns.without(:role_id),
|
32
32
|
unique: true, where: 'role_id IS NULL', name: :index_adjustable_schema_relationships_uniqueness_without_role
|
33
33
|
}
|
34
34
|
end
|
@@ -10,21 +10,32 @@ module AdjustableSchema
|
|
10
10
|
refine String do
|
11
11
|
def passivize
|
12
12
|
self
|
13
|
-
.
|
14
|
-
|
13
|
+
.presence
|
14
|
+
&.sub(/((:?[aeiou]+[^aeiou]+){2,})(?:or|ant|ion|e?ment)$/, '\1ed')
|
15
|
+
&.sub(/((:?[aeiou]+[^aeiou]+){1,})(?:ing)$/, '\1ed')
|
16
|
+
&.sub(/(?:e*|ed|er)$/, '\1ed')
|
17
|
+
.to_s
|
15
18
|
end
|
16
19
|
end
|
17
20
|
end
|
18
21
|
|
19
22
|
using Inflections
|
20
23
|
|
21
|
-
memoize def name
|
22
|
-
|
24
|
+
memoize def name name = object_name
|
25
|
+
name
|
23
26
|
.to_s
|
24
27
|
.tableize
|
25
28
|
.to_sym
|
26
29
|
end
|
27
30
|
|
31
|
+
def object_name
|
32
|
+
if role
|
33
|
+
name_with_role
|
34
|
+
else
|
35
|
+
name_without_role
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
28
39
|
memoize def target_name
|
29
40
|
target.model_name.unnamespaced
|
30
41
|
.split('::')
|
@@ -51,17 +62,20 @@ module AdjustableSchema
|
|
51
62
|
end
|
52
63
|
end
|
53
64
|
|
54
|
-
|
65
|
+
def name_without_role
|
55
66
|
if recursive?
|
56
67
|
Config.association_directions
|
57
68
|
.self[direction]
|
69
|
+
.to_s
|
58
70
|
else
|
59
71
|
target_name
|
60
72
|
end
|
61
73
|
end
|
62
74
|
|
63
|
-
def
|
64
|
-
|
75
|
+
def roleless_name = name(target_name)
|
76
|
+
|
77
|
+
def name_for_any (name = object_name) = :"#{name}ful"
|
78
|
+
def name_for_none(name = object_name) = :"#{name}less"
|
65
79
|
end
|
66
80
|
end
|
67
81
|
end
|
@@ -24,8 +24,8 @@ module AdjustableSchema
|
|
24
24
|
unless role
|
25
25
|
# HACK: using `try` to overcome a Rails bug
|
26
26
|
# (see https://github.com/rails/rails/issues/40109)
|
27
|
-
has_many
|
28
|
-
|
27
|
+
has_many roleless_name, -> { try :roleless }, **options if
|
28
|
+
child?
|
29
29
|
|
30
30
|
define_role_methods
|
31
31
|
end
|
@@ -33,6 +33,12 @@ module AdjustableSchema
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def recursive? = target == owner
|
36
|
+
def roleless? = !role
|
37
|
+
def source? = direction == :source
|
38
|
+
def target? = direction == :target
|
39
|
+
def child? = (recursive? and source?)
|
40
|
+
def parent? = (recursive? and target?)
|
41
|
+
def hierarchy? = (child? and roleless?)
|
36
42
|
|
37
43
|
private
|
38
44
|
|
@@ -46,22 +52,36 @@ module AdjustableSchema
|
|
46
52
|
end
|
47
53
|
|
48
54
|
def define_scopes
|
49
|
-
name
|
55
|
+
name = relationships_name
|
56
|
+
roleless_name = self.roleless_name
|
50
57
|
|
51
58
|
{
|
52
59
|
name_for_any => -> { where.associated name },
|
53
60
|
name_for_none => -> { where.missing name },
|
61
|
+
|
62
|
+
**({
|
63
|
+
name_for_any( target_name) => -> { where.associated roleless_name },
|
64
|
+
name_for_none(target_name) => -> { where.missing roleless_name },
|
65
|
+
} if hierarchy?),
|
54
66
|
}
|
55
67
|
.reject { owner.singleton_class.method_defined? _1 }
|
56
68
|
.each { owner.scope _1, _2 }
|
57
69
|
end
|
58
70
|
|
59
71
|
def define_methods
|
60
|
-
name
|
72
|
+
name = self.name
|
73
|
+
roleless_name = self.roleless_name
|
61
74
|
|
62
75
|
{
|
63
76
|
name_for_any => -> { send(name).any? },
|
64
77
|
name_for_none => -> { send(name).none? },
|
78
|
+
|
79
|
+
**(hierarchy? ? {
|
80
|
+
name_for_any( target_name) => -> { send(roleless_name).any? },
|
81
|
+
name_for_none(target_name) => -> { send(roleless_name).none? },
|
82
|
+
intermediate: -> { send(roleless_name).one? },
|
83
|
+
branching: -> { send(roleless_name).many? },
|
84
|
+
} : {}),
|
65
85
|
}
|
66
86
|
.transform_keys {"#{_1}?" }
|
67
87
|
.reject { owner.method_defined? _1 }
|
@@ -11,7 +11,7 @@ module AdjustableSchema
|
|
11
11
|
config(:shortcut).tap do |shortcuts|
|
12
12
|
def shortcuts.opposite to: nil
|
13
13
|
if to
|
14
|
-
values.
|
14
|
+
values.grep_v(to).sole
|
15
15
|
else
|
16
16
|
transform_values { opposite to: _1 }
|
17
17
|
end
|
@@ -28,7 +28,7 @@ module AdjustableSchema
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def opposite to:
|
31
|
-
|
31
|
+
grep_v(to).sole
|
32
32
|
end
|
33
33
|
|
34
34
|
private
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: adjustable_schema
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Senko
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date: 2024-
|
10
|
+
date: 2024-11-08 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: rails
|
@@ -111,8 +110,7 @@ licenses:
|
|
111
110
|
metadata:
|
112
111
|
homepage_uri: https://github.com/Alexander-Senko/adjustable_schema
|
113
112
|
source_code_uri: https://github.com/Alexander-Senko/adjustable_schema
|
114
|
-
changelog_uri: https://github.com/Alexander-Senko/adjustable_schema/blob/v0.
|
115
|
-
post_install_message:
|
113
|
+
changelog_uri: https://github.com/Alexander-Senko/adjustable_schema/blob/v0.8.0/CHANGELOG.md
|
116
114
|
rdoc_options: []
|
117
115
|
require_paths:
|
118
116
|
- lib
|
@@ -127,8 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
125
|
- !ruby/object:Gem::Version
|
128
126
|
version: '0'
|
129
127
|
requirements: []
|
130
|
-
rubygems_version: 3.
|
131
|
-
signing_key:
|
128
|
+
rubygems_version: 3.6.0.dev
|
132
129
|
specification_version: 4
|
133
130
|
summary: Adjustable data schemas for Rails
|
134
131
|
test_files: []
|