active_record-associated_object 0.8.2 → 0.8.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/Gemfile.lock +1 -1
- data/README.md +74 -1
- data/lib/active_record/associated_object/railtie.rb +7 -7
- data/lib/active_record/associated_object/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4212b6fcecceb21ae133688c2a3332d29b8c0f5760f5a22a8ba3450037a95b20
|
4
|
+
data.tar.gz: 4b96fde3db82d00a3c94153cb9b212f1091bd0040d7d9771d300f2a0a0147d6f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 262b75fdf718925e7772b7c1dd4e49ab6b73f6706be97081433712a4f3efef524b1677194ff5376415fe32e770bfa080afd5b347c2ccf78786517dfe5a21a9fb
|
7
|
+
data.tar.gz: 47c40f2a351cd49fe9bc5e0488d37ce79bcb3d30332b3aabbaff681ef7ac7f937d81d01c60d6b7f8393d3fc28f7fa92fb9b4d5eb99ae607d95d0389deea12764
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -60,7 +60,7 @@ We've fixed this so you don't need to care, but this is what's happening.
|
|
60
60
|
> `has_object` only requires a namespace and an initializer that takes a single argument. The above `Post::Publisher` is perfectly valid as an Associated Object — same goes for `class Post::Publisher < Data.define(:post); end`.
|
61
61
|
|
62
62
|
> [!TIP]
|
63
|
-
> You can pass multiple names too: `has_object :publisher, :classified, :fortification`. I recommend `-[i]er`, `-[i]ed` and `-ion` as the general naming conventions for your Associated Objects.
|
63
|
+
> You can pass multiple names too: `has_object :seats, :entitlements, :publisher, :classified, :fortification`. I recommend `-s`, `-[i]er`, `-[i]ed` and `-ion` as the general naming conventions for your Associated Objects.
|
64
64
|
|
65
65
|
> [!TIP]
|
66
66
|
> Plural Associated Object names are also supported: `Account.has_object :seats` will look up `Account::Seats`.
|
@@ -87,6 +87,17 @@ end
|
|
87
87
|
|
88
88
|
### See Associated Objects in action
|
89
89
|
|
90
|
+
#### RubyVideo.dev
|
91
|
+
|
92
|
+
The team at https://www.rubyvideo.dev has been using Associated Objects to clarify the boundaries of their Active Records and collaborator Associated Objects.
|
93
|
+
|
94
|
+
See the usage in the source here:
|
95
|
+
|
96
|
+
- [`ActiveRecord::AssociatedObject` instances](https://github.com/search?q=repo%3Aadrienpoly%2Frubyvideo%20ActiveRecord%3A%3AAssociatedObject&type=code)
|
97
|
+
- [`has_object` calls](https://github.com/search?q=repo%3Aadrienpoly%2Frubyvideo+has_object&type=code)
|
98
|
+
|
99
|
+
#### Flipper
|
100
|
+
|
90
101
|
The team at [Flipper](https://www.flippercloud.io) used Associated Objects to help keep their new billing structure clean.
|
91
102
|
|
92
103
|
You can see real life examples in these blog posts:
|
@@ -240,6 +251,68 @@ class Post::PublisherTest < ActiveSupport::TestCase
|
|
240
251
|
end
|
241
252
|
```
|
242
253
|
|
254
|
+
### Polymorphic Associated Objects
|
255
|
+
|
256
|
+
If you want to share logic between associated objects, you can do so via standard Ruby modules:
|
257
|
+
|
258
|
+
```ruby
|
259
|
+
# app/models/pricing.rb
|
260
|
+
module Pricing
|
261
|
+
# If you need to share an `extension` across associated objects you can override `Module::included` like this:
|
262
|
+
def self.included(object) = object.extension do
|
263
|
+
# Add common integration methods onto `Account`/`User` when the module is included.
|
264
|
+
# See the `extension` block in the `Extending` section above for an example.
|
265
|
+
end
|
266
|
+
|
267
|
+
def price_set?
|
268
|
+
# Instead of referring to `account` or `user`, use the `record` method to target either.
|
269
|
+
record.price_cents.positive?
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
# app/models/account/pricing.rb
|
274
|
+
class Account::Pricing < ActiveRecord::AssociatedObject
|
275
|
+
include ::Pricing
|
276
|
+
end
|
277
|
+
|
278
|
+
# app/models/user/pricing.rb
|
279
|
+
class User::Pricing < ActiveRecord::AssociatedObject
|
280
|
+
include ::Pricing
|
281
|
+
end
|
282
|
+
```
|
283
|
+
|
284
|
+
Now we can call `account.pricing.price_set?` & `user.pricing.price_set?`.
|
285
|
+
|
286
|
+
> [!NOTE]
|
287
|
+
> Polymorphic Associated Objects are definitely a more advanced topic,
|
288
|
+
> so you need to know your Ruby module hierarchy and how to track what `self` changes to fairly well.
|
289
|
+
|
290
|
+
#### Using `ActiveSupport::Concern` as an alternative
|
291
|
+
|
292
|
+
If you prefer the look of Active Support concerns, here's the equivalent to the above Ruby module:
|
293
|
+
|
294
|
+
```ruby
|
295
|
+
# app/models/pricing.rb
|
296
|
+
module Pricing
|
297
|
+
extend ActiveSupport::Concern
|
298
|
+
|
299
|
+
included do
|
300
|
+
extension do
|
301
|
+
# Add common integration methods onto `Account`/`User` when the concern is included.
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
def price_set?
|
306
|
+
# Instead of referring to `account` or `user`, use the `record` method to target either.
|
307
|
+
record.price_cents.positive?
|
308
|
+
end
|
309
|
+
end
|
310
|
+
```
|
311
|
+
|
312
|
+
Active Support concerns have some extra features that standard Ruby modules don't, like support for deeply-nested concerns and `class_methods do`.
|
313
|
+
|
314
|
+
In this case, if you're reaching for those, you're probably building something too intricate and potentially brittle.
|
315
|
+
|
243
316
|
### Active Job integration via GlobalID
|
244
317
|
|
245
318
|
Associated Objects include `GlobalID::Identification` and have automatic Active Job serialization support that looks like this:
|
@@ -6,14 +6,14 @@ class ActiveRecord::AssociatedObject::Railtie < Rails::Railtie
|
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
-
initializer "
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
9
|
+
initializer "active_job.performs" do
|
10
|
+
require "active_job/performs"
|
11
|
+
ActiveRecord::AssociatedObject.extend ActiveJob::Performs if defined?(ActiveJob::Performs)
|
12
|
+
rescue LoadError
|
13
|
+
# We haven't bundled active_job-performs, so we're continuing without it.
|
14
|
+
end
|
16
15
|
|
16
|
+
initializer "object_association.setup" do
|
17
17
|
ActiveSupport.on_load :active_record do
|
18
18
|
require "active_record/associated_object/object_association"
|
19
19
|
include ActiveRecord::AssociatedObject::ObjectAssociation
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_record-associated_object
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kasper Timm Hansen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-12-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|