belongs_to_polymorphic 0.1.0 → 0.1.3
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 +39 -8
- data/lib/belongs_to_polymorphic/associations.rb +61 -0
- data/lib/belongs_to_polymorphic/version.rb +3 -1
- data/lib/belongs_to_polymorphic.rb +8 -40
- metadata +39 -51
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d1c2af190a259601a400ab83fc7878d3ba1e9ba155d08920b687d41b551f2af
|
4
|
+
data.tar.gz: e00c21112f674af04124f846d56b9d5c611f29038490aa021ceba0bef87abdd6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a3212e59e3449e9f2da0038cb45bb73b6d9ff212624145ee73a3b98f7f40933c774803008ee8581d6074fdef6aa5bef6d2985c30b3e1e0796daf8999d794ab0
|
7
|
+
data.tar.gz: bb848815e83b195207af66184440442f70416eaf09d90cf054c3a54ea96266d3812873f8ec81dae3567c82df5bf9164fbadb84ceb1cf995aaf43ef7c74c2a3c2
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
An ActiveRecord extension defining the concept *belongs to polymorphic*, which allows us to use polymorphic associations (belongs_to) and restrict which classes are allowed to be related to.
|
4
4
|
|
5
5
|
|
6
|
-
The base idea
|
6
|
+
The base idea was taken from this blogpost: [Improve ActiveRecord Polymorphic Associations - Head of engineering at Product Hunt](https://blog.rstankov.com/allowed-class-names-in-activerecord-polymorphic-associations/).
|
7
7
|
|
8
8
|
## Installation
|
9
9
|
|
@@ -27,16 +27,16 @@ In your model you can do the following:
|
|
27
27
|
|
28
28
|
```ruby
|
29
29
|
class Book < ActiveRecord::Base
|
30
|
-
belongs_to_polymorphic :owner, allowed_classes: [
|
30
|
+
belongs_to_polymorphic :owner, allowed_classes: [User, Publisher]
|
31
31
|
end
|
32
32
|
```
|
33
33
|
|
34
34
|
You can also add any options that a regular `belongs_to` with `polymorphic: true` could use.
|
35
35
|
|
36
|
-
By using this you create a polymorphic relationship in `Book` called `
|
36
|
+
By using this you create a polymorphic relationship in `Book` called `owner` which can be a `User` or a `Publisher`.
|
37
37
|
If you try to set an `owner` from a class rather than the aforementioend ones, it will return the following error:
|
38
38
|
```ruby
|
39
|
-
|
39
|
+
#ActiveRecord::RecordInvalid: Validation failed: Owner type OtherThing class is not an allowed class.
|
40
40
|
```
|
41
41
|
|
42
42
|
It also automatically adds some helpers
|
@@ -53,15 +53,46 @@ Instance:
|
|
53
53
|
|
54
54
|
```ruby
|
55
55
|
class Book < ActiveRecord::Base
|
56
|
-
belongs_to_polymorphic :owner, allowed_classes: [Publisher::
|
56
|
+
belongs_to_polymorphic :owner, allowed_classes: [Publisher::User, Publisher]
|
57
57
|
end
|
58
58
|
```
|
59
59
|
|
60
60
|
It will allow you to use:
|
61
|
-
- `Book.with_owner(Publisher::
|
62
|
-
- `Book.
|
63
|
-
- `book.
|
61
|
+
- `Book.with_owner(Publisher::User)`
|
62
|
+
- `Book.with_owner_publisher_user`
|
63
|
+
- `book.owner_type_publisher_user?`
|
64
|
+
|
65
|
+
## I18n
|
66
|
+
|
67
|
+
Belongs to Polymoprhic uses I18n to define the not allowed class error. To customize it, you can set up your locale file:
|
68
|
+
|
69
|
+
```yaml
|
70
|
+
en:
|
71
|
+
belongs_to_polymoprhic:
|
72
|
+
errors:
|
73
|
+
messages:
|
74
|
+
class_not_allowed: "%{class} is not an allowed class"
|
75
|
+
```
|
76
|
+
|
77
|
+
## Development
|
78
|
+
|
79
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
80
|
+
|
81
|
+
## Contributing
|
82
|
+
|
83
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/gogrow-dev/belongs_to_polymorphic. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/gogrow-dev/belongs_to_polymorphic/blob/main/CODE_OF_CONDUCT.md).
|
64
84
|
|
65
85
|
## License
|
66
86
|
|
67
87
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
88
|
+
|
89
|
+
## Code of Conduct
|
90
|
+
|
91
|
+
Everyone interacting in the belongs_to_polymorphic project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/gogrow-dev/belongs_to_polymorphic/blob/main/CODE_OF_CONDUCT.md).
|
92
|
+
|
93
|
+
## Credits
|
94
|
+
|
95
|
+
belongs_to_polymorphic is maintained by [GoGrow](https://gogrow.dev) with the help of our
|
96
|
+
[contributors](https://github.com/gogrow-dev/belongs_to_polymorphic/contributors).
|
97
|
+
|
98
|
+
[<img src="https://user-images.githubusercontent.com/9309458/180014465-00477428-fd76-48f6-b984-5b401b8ce241.svg" height="50"/>](https://gogrow.dev)
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BelongsToPolymorphic
|
4
|
+
module Associations
|
5
|
+
def self.included(base)
|
6
|
+
base.extend ClassMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def belongs_to_polymorphic(name, allowed_classes:, **options)
|
11
|
+
allowed_classes = Array.wrap(allowed_classes)
|
12
|
+
belongs_to name, polymorphic: true, **options
|
13
|
+
|
14
|
+
validates "#{name}_type", inclusion: {
|
15
|
+
in: classes(allowed_classes, options),
|
16
|
+
message: I18n.t('belongs_to_polymorphic.errors.messages.class_not_allowed',
|
17
|
+
class: '%<value>s')
|
18
|
+
}
|
19
|
+
|
20
|
+
define_singleton_method("#{name}_types") { allowed_classes }
|
21
|
+
define_generic_finder_method(name)
|
22
|
+
define_scopes_and_instance_methods(name, allowed_classes)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def classes(allowed_classes, options)
|
28
|
+
classes = allowed_classes.map(&:name)
|
29
|
+
classes << nil if options[:optional]
|
30
|
+
classes
|
31
|
+
end
|
32
|
+
|
33
|
+
# Generates a generic finder method
|
34
|
+
def define_generic_finder_method(name)
|
35
|
+
define_singleton_method("with_#{name}") do |type|
|
36
|
+
type = case type
|
37
|
+
when Class then type.name
|
38
|
+
when String then type
|
39
|
+
else type.class.name
|
40
|
+
end
|
41
|
+
where("#{name}_type" => type)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def define_scopes_and_instance_methods(name, allowed_classes)
|
46
|
+
allowed_classes.each do |model|
|
47
|
+
model_name = model.name
|
48
|
+
model_name_sanitized = model_name.underscore.tr('/', '_')
|
49
|
+
# generates scope for each allowed class
|
50
|
+
scope "with_#{name}_#{model_name_sanitized}",
|
51
|
+
-> { where("#{name}_type" => model_name) }
|
52
|
+
|
53
|
+
# generates instance method for each allowed class to check if type is that class
|
54
|
+
define_method("#{name}_type_#{model_name_sanitized}?") do
|
55
|
+
public_send("#{name}_type") == model_name
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -1,44 +1,12 @@
|
|
1
|
-
|
2
|
-
require 'active_support/concern'
|
3
|
-
|
4
|
-
module BelongsToPolymorphic
|
5
|
-
extend ActiveSupport::Concern
|
1
|
+
# frozen_string_literal: true
|
6
2
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
allowed_classes = Array.new(allowed_classes)
|
11
|
-
belongs_to name, polymorphic: true, **options
|
12
|
-
classes = allowed_classes.map(&:name)
|
13
|
-
classes << nil if options[:optional]
|
14
|
-
validates "#{name}_type", inclusion: { in: classes }
|
15
|
-
define_singleton_method("#{name}_types") { allowed_classes }
|
16
|
-
|
17
|
-
# generates a generic finder method
|
18
|
-
define_singleton_method("with_#{name}") do |type|
|
19
|
-
type = case type
|
20
|
-
when Class then type.name
|
21
|
-
when String then type
|
22
|
-
else type.class.name
|
23
|
-
end
|
24
|
-
where("#{name}_type" => type)
|
25
|
-
end
|
3
|
+
require 'active_record'
|
4
|
+
require 'belongs_to_polymorphic/version'
|
5
|
+
require 'belongs_to_polymorphic/associations'
|
26
6
|
|
27
|
-
|
28
|
-
model_name = model.name
|
29
|
-
model_name_sanitized = model_name.underscore.tr('/', '_')
|
30
|
-
# generates scope for each allowed class
|
31
|
-
scope "with_#{name}_#{model_name_sanitized}",
|
32
|
-
-> { where("#{name}_type" => model_name) }
|
7
|
+
I18n.load_path << File.expand_path('config/locales/en.yml')
|
33
8
|
|
34
|
-
|
35
|
-
define_method("#{name}_type_#{model_name_sanitized}?") do
|
36
|
-
public_send("#{name}_type") == model_name
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
# rubocop:enable Metrics/AbcSize
|
41
|
-
end
|
42
|
-
end
|
9
|
+
module BelongsToPolymorphic; end
|
43
10
|
|
44
|
-
ActiveRecord::Base
|
11
|
+
# Extend ActiveRecord::Base with belongs to polymorphic associations
|
12
|
+
ActiveRecord::Base.include BelongsToPolymorphic::Associations
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: belongs_to_polymorphic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicolas Erlichman
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-07-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,70 +16,62 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 5.
|
20
|
-
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: 5.0.0
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rake
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
19
|
+
version: '5.2'
|
20
|
+
- - "<"
|
32
21
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :
|
22
|
+
version: '8.0'
|
23
|
+
type: :runtime
|
35
24
|
prerelease: false
|
36
25
|
version_requirements: !ruby/object:Gem::Requirement
|
37
26
|
requirements:
|
38
27
|
- - ">="
|
39
28
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
29
|
+
version: '5.2'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '8.0'
|
41
33
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
34
|
+
name: database_cleaner-active_record
|
43
35
|
requirement: !ruby/object:Gem::Requirement
|
44
36
|
requirements:
|
45
|
-
- - "
|
37
|
+
- - "~>"
|
46
38
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
39
|
+
version: 1.8.0
|
48
40
|
type: :development
|
49
41
|
prerelease: false
|
50
42
|
version_requirements: !ruby/object:Gem::Requirement
|
51
43
|
requirements:
|
52
|
-
- - "
|
44
|
+
- - "~>"
|
53
45
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
46
|
+
version: 1.8.0
|
55
47
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
48
|
+
name: rake
|
57
49
|
requirement: !ruby/object:Gem::Requirement
|
58
50
|
requirements:
|
59
|
-
- - "
|
51
|
+
- - "~>"
|
60
52
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
53
|
+
version: 13.0.6
|
62
54
|
type: :development
|
63
55
|
prerelease: false
|
64
56
|
version_requirements: !ruby/object:Gem::Requirement
|
65
57
|
requirements:
|
66
|
-
- - "
|
58
|
+
- - "~>"
|
67
59
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
60
|
+
version: 13.0.6
|
69
61
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
62
|
+
name: rspec
|
71
63
|
requirement: !ruby/object:Gem::Requirement
|
72
64
|
requirements:
|
73
|
-
- - "
|
65
|
+
- - "~>"
|
74
66
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
67
|
+
version: 3.11.0
|
76
68
|
type: :development
|
77
69
|
prerelease: false
|
78
70
|
version_requirements: !ruby/object:Gem::Requirement
|
79
71
|
requirements:
|
80
|
-
- - "
|
72
|
+
- - "~>"
|
81
73
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
74
|
+
version: 3.11.0
|
83
75
|
- !ruby/object:Gem::Dependency
|
84
76
|
name: simplecov
|
85
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -95,25 +87,19 @@ dependencies:
|
|
95
87
|
- !ruby/object:Gem::Version
|
96
88
|
version: 0.17.1
|
97
89
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
90
|
+
name: sqlite3
|
99
91
|
requirement: !ruby/object:Gem::Requirement
|
100
92
|
requirements:
|
101
|
-
- - "
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '5.2'
|
104
|
-
- - "<"
|
93
|
+
- - "~>"
|
105
94
|
- !ruby/object:Gem::Version
|
106
|
-
version:
|
107
|
-
type: :
|
95
|
+
version: 1.4.2
|
96
|
+
type: :development
|
108
97
|
prerelease: false
|
109
98
|
version_requirements: !ruby/object:Gem::Requirement
|
110
99
|
requirements:
|
111
|
-
- - "
|
112
|
-
- !ruby/object:Gem::Version
|
113
|
-
version: '5.2'
|
114
|
-
- - "<"
|
100
|
+
- - "~>"
|
115
101
|
- !ruby/object:Gem::Version
|
116
|
-
version:
|
102
|
+
version: 1.4.2
|
117
103
|
description: ActiveRecord extension - Polymorphic associations with restricted allowed
|
118
104
|
classes.
|
119
105
|
email:
|
@@ -125,13 +111,15 @@ files:
|
|
125
111
|
- LICENSE.txt
|
126
112
|
- README.md
|
127
113
|
- lib/belongs_to_polymorphic.rb
|
114
|
+
- lib/belongs_to_polymorphic/associations.rb
|
128
115
|
- lib/belongs_to_polymorphic/version.rb
|
129
|
-
homepage: https://
|
116
|
+
homepage: https://gogrow.dev
|
130
117
|
licenses:
|
131
118
|
- MIT
|
132
119
|
metadata:
|
133
|
-
source_code_uri: https://
|
134
|
-
|
120
|
+
source_code_uri: https://gogrow.dev
|
121
|
+
rubygems_mfa_required: 'true'
|
122
|
+
post_install_message:
|
135
123
|
rdoc_options: []
|
136
124
|
require_paths:
|
137
125
|
- lib
|
@@ -146,8 +134,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
134
|
- !ruby/object:Gem::Version
|
147
135
|
version: '0'
|
148
136
|
requirements: []
|
149
|
-
rubygems_version: 3.
|
150
|
-
signing_key:
|
137
|
+
rubygems_version: 3.3.7
|
138
|
+
signing_key:
|
151
139
|
specification_version: 4
|
152
140
|
summary: ActiveRecord extension - Polymorphic associations with restricted allowed
|
153
141
|
classes.
|