active_record-associated_object 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '049c38f6aeb242c8ccfee9c15d3e29ace1c8f69eaf67619cdb38b09e5dd97514'
4
- data.tar.gz: 911ce88d3257b0db22169f325ca2059b12ecdd8bb7121d7a37368588dce37262
3
+ metadata.gz: d7a508d24fc9467600956a207ee83775b3618ccfc8be21a9c11e1caa72a11172
4
+ data.tar.gz: '0360292507cf0e901140b9fe4003bd33aca10aff9d91b01b759e4ce75497a61f'
5
5
  SHA512:
6
- metadata.gz: 0ee5964826318cb28a0a1d4c9e0a383b157e4ec0f2dd908b944c5eec68ddc7179d0d43be37bb65316c91e42318a6104b67eccd7d72194b99b4f3284312204692
7
- data.tar.gz: 61df4cf5bc61dd0109650ce1aa95bc1f9e79fd99c2da6e2757429b71cda10b1423d6dda7f29310390fa0c5d01b0a5b77563de4151c277316e7a3e57edf16c699
6
+ metadata.gz: '04940ddec3fc5446ba945df9f3daeff22550e81cf55f1e61e02b79af687adfc376f05e1148a6fb0e7ff17ab5df1a4539fe1d1c8bde456b986561df8ef4714e93'
7
+ data.tar.gz: 49ff34bb1945649479481ef7502585a124ee1464c67bc29f8ccb3335a53cfd0858790fbeebb976e3dfa1f055d12c085bb26ab2a7d054bed2ef51420f40cf83d5
data/CHANGELOG.md CHANGED
@@ -1,4 +1,20 @@
1
- ## [Unreleased]
1
+ ## [0.2.0] - 2022-04-21
2
+
3
+ - Require a `has_object` call on the record side to associate an object.
4
+
5
+ ```ruby
6
+ class Post < ActiveRecord::Base
7
+ has_object :publisher
8
+ end
9
+ ```
10
+
11
+ - Allow `has_object` to pass callbacks onto the associated object.
12
+
13
+ ```ruby
14
+ class Post < ActiveRecord::Base
15
+ has_object :publisher, after_touch: true, before_destroy: :prevent_errant_post_destroy
16
+ end
17
+ ```
2
18
 
3
19
  ## [0.1.0] - 2022-04-19
4
20
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- active_record-associated_object (0.1.0)
4
+ active_record-associated_object (0.2.0)
5
5
  activerecord (>= 6.1)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -7,6 +7,8 @@ Associate a Ruby PORO with an Active Record class and have it quack like one. Bu
7
7
  ```ruby
8
8
  # app/models/post.rb
9
9
  class Post < ActiveRecord::Base
10
+ # `has_object` defines a `publisher` method that calls Post::Publisher.new(post).
11
+ has_object :publisher, after_touch: true, before_destroy: :prevent_post_destroy
10
12
  end
11
13
 
12
14
  # Create a standard PORO, but derive attributes from the Post:: namespace and its primary key.
@@ -27,9 +29,6 @@ class Post::Publisher < ActiveRecord::AssociatedObject
27
29
  end
28
30
  end
29
31
 
30
- # Post now has a publisher too.
31
- Post.first.publisher # => Post::Publisher.new(self) # Where self is Post.first.
32
-
33
32
  class Post::Publisher::PublishJob < ActiveJob::Base
34
33
  def perform(publisher)
35
34
  # Automatic integration via GlobalID means you don't have to do `post.publisher`.
@@ -38,6 +37,32 @@ class Post::Publisher::PublishJob < ActiveJob::Base
38
37
  end
39
38
  ```
40
39
 
40
+ ### Passing callbacks onto the associated object
41
+
42
+ `has_object` accepts a hash of callbacks to pass.
43
+
44
+ ```ruby
45
+ class Post < ActiveRecord::Base
46
+ # Callbacks can be passed too to a specific method.
47
+ has_object :publisher, after_touch: true, before_destroy: :prevent_post_destroy
48
+
49
+ # The above is the same as writing:
50
+ after_touch { publisher.after_touch }
51
+ before_destroy { publisher.prevent_errant_post_destroy }
52
+ end
53
+
54
+ class Post::Publisher < ActiveRecord::AssociatedObject
55
+ def after_touch
56
+ # Respond to the after_touch on the Post.
57
+ end
58
+
59
+ def prevent_errant_post_destroy
60
+ # Passed callbacks can throw :abort too, and in this example prevent post.destroy.
61
+ throw :abort unless haha_business?
62
+ end
63
+ end
64
+ ```
65
+
41
66
  ## Installation
42
67
 
43
68
  Install the gem and add to the application's Gemfile by executing:
@@ -0,0 +1,17 @@
1
+ module ActiveRecord::AssociatedObject::ObjectAssociation
2
+ def has_object(*names, **callbacks)
3
+ methods = names.map do |name|
4
+ "def #{name}; @#{name} ||= #{self.name}::#{name.to_s.classify}.new(self); end"
5
+ end
6
+
7
+ class_eval methods.join("\n\n"), __FILE__, __LINE__ + 1
8
+
9
+ passes = names.flat_map do |name|
10
+ callbacks.map do |callback, method|
11
+ "#{callback} { #{name}.#{method == true ? callback : method} }"
12
+ end
13
+ end
14
+
15
+ class_eval passes.join("\n\n"), __FILE__, __LINE__ + 1
16
+ end
17
+ end
@@ -3,4 +3,11 @@ class ActiveRecord::AssociatedObject::Railtie < Rails::Railtie
3
3
  ActiveRecord::AssociatedObject.include Kredis::Attributes if defined?(Kredis)
4
4
  ActiveRecord::AssociatedObject.include GlobalID::Identification if defined?(GlobalID)
5
5
  end
6
+
7
+ initializer "object_association.setup" do
8
+ ActiveSupport.on_load :active_record do
9
+ require "active_record/associated_object/object_association"
10
+ ActiveRecord::Base.extend ActiveRecord::AssociatedObject::ObjectAssociation
11
+ end
12
+ end
6
13
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ActiveRecord
4
4
  class AssociatedObject
5
- VERSION = "0.1.0"
5
+ VERSION = "0.2.0"
6
6
  end
7
7
  end
@@ -13,12 +13,6 @@ class ActiveRecord::AssociatedObject
13
13
  define_singleton_method(:record_klass) { record_klass }
14
14
  define_singleton_method(:attribute_name) { attribute_name }
15
15
  delegate :record_klass, :attribute_name, to: :class
16
-
17
- record_klass.class_eval <<~RUBY, __FILE__, __LINE__ + 1
18
- def #{attribute_name}
19
- @#{attribute_name} ||= #{klass}.new(self)
20
- end
21
- RUBY
22
16
  end
23
17
 
24
18
  def respond_to_missing?(...) = record_klass.respond_to?(...) || super
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.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kasper Timm Hansen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-04-20 00:00:00.000000000 Z
11
+ date: 2022-04-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -39,6 +39,7 @@ files:
39
39
  - Rakefile
40
40
  - active_record-associated_object.gemspec
41
41
  - lib/active_record/associated_object.rb
42
+ - lib/active_record/associated_object/object_association.rb
42
43
  - lib/active_record/associated_object/railtie.rb
43
44
  - lib/active_record/associated_object/version.rb
44
45
  homepage: https://github.com/kaspth/active_record-associated_object