active_record_compose 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f87118b489cd061b4912c625ec2b9bdc91ad4b024e69cd6a6c45ab9c884018f3
4
- data.tar.gz: 22eec41668831a5f97d5935502d4c4d61de723b78dd2f70d2dca2bbfb4d9fa52
3
+ metadata.gz: b6881ca78dfbf9fc5fc15cf72ac6073c4780d4b7b32747fc1b58a0147adce3fe
4
+ data.tar.gz: 37a7dfa3d4de10d2a35ea6a10a9d3e131809eba27ef60cb5b917b1b736f209e7
5
5
  SHA512:
6
- metadata.gz: 180d9e45c2e18dc362d0169a22040759614882e09254c4fc8ad80ead07302c280446cab288c5042f81f33d339ab00b114d888536f691ab817063dc5dc6765cc0
7
- data.tar.gz: a4ba3164829709bbdbb38f0232b555ef210b6ce0783348317c430ffb9d1931f9b9b48bec3f28fefe757ee9ce6f9c8b3dcfb3a53ec557650eab4d6e7a8870e13f
6
+ metadata.gz: abc371fd146961cec4f4b8d234367734e772aaab9b08450debb1a79adba4fa5703fd169090d1d636c95f56a89ec0184e5c7db2f4bb04f61609dc925e5fe08ffa
7
+ data.tar.gz: 427c2bd3151f1fba2541795aa36f645952a87930ccd92fb0d1d7a9a1144d7486c30180cd0b021c1660aab380dd1cb887191fe37c1dc069b0d3cd5197f7c3ace0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## [Unreleased]
2
2
 
3
- ## [0.1.0] - 2023-07-29
3
+ ## [0.1.1] - 2024-01-08
4
+
5
+ - fix 0.1.0 release date.
6
+ - add doc.
7
+ - Make it easier for application developers to work with `#models`
8
+
9
+ ## [0.1.0] - 2024-01-06
4
10
 
5
11
  - Initial release
data/README.md CHANGED
@@ -199,7 +199,7 @@ It provides a macro description that expresses access to the attributes of the A
199
199
 
200
200
  ```ruby
201
201
  class AccountRegistration < ActiveRecordCompose::Model
202
- def initialize(account)
202
+ def initialize(account, attributes = {})
203
203
  @account = account
204
204
  super(attributes)
205
205
  models.push(account)
@@ -1,6 +1,39 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecordCompose
4
+ # = Delegate \Attribute
5
+ #
6
+ # It provides a macro description that expresses access to the attributes of the AR model through delegation.
7
+ #
8
+ # class AccountRegistration < ActiveRecordCompose::Model
9
+ # def initialize(account, attributes = {})
10
+ # @account = account
11
+ # super(attributes)
12
+ # models.push(account)
13
+ # end
14
+ #
15
+ # attribute :original_attribute, :string, default: 'qux'
16
+ #
17
+ # # like a `delegate :name, :name=, to: :account`
18
+ # delegate_attribute :name, to: :account
19
+ #
20
+ # private
21
+ #
22
+ # attr_reader :account
23
+ # end
24
+ #
25
+ # account = Account.new
26
+ # account.name = 'foo'
27
+ #
28
+ # registration = AccountRegistration.new(account)
29
+ # registration.name #=> 'foo' # delegate to account#name
30
+ #
31
+ # registration.name = 'bar' # delegate to account#name=
32
+ # account.name #=> 'bar'
33
+ #
34
+ # # Attributes defined in delegate_attribute will be included in the original `#attributes`.
35
+ # registration.attributes #=> { 'original_attribute' => 'qux', 'name' => 'bar' }
36
+ #
4
37
  module DelegateAttribute
5
38
  extend ActiveSupport::Concern
6
39
 
@@ -1,40 +1,55 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'active_support/core_ext/object'
4
+
3
5
  module ActiveRecordCompose
4
6
  class InnerModel
5
- def initialize(inner_model, context: :save)
6
- @inner_model = inner_model
7
+ # @param model [Object] the model instance.
8
+ # @param context [Symbol] :save or :destroy
9
+ def initialize(model, context: :save)
10
+ @model = model
7
11
  @context = context
8
12
  end
9
13
 
10
- delegate :errors, to: :inner_model
14
+ delegate :errors, to: :model
11
15
 
16
+ # @return [Symbol] :save or :destroy
12
17
  def context
13
- @context.respond_to?(:call) ? @context.call(inner_model) : @context
18
+ ret = @context.respond_to?(:call) ? @context.call(model) : @context
19
+ ret.presence_in(%i[save destroy]) || :save
14
20
  end
15
21
 
22
+ # @return [InnerModel] self
16
23
  def save!
17
24
  case context
18
25
  when :destroy
19
- inner_model.destroy!
26
+ model.destroy!
20
27
  else
21
- inner_model.save!
28
+ model.save!
22
29
  end
23
30
  end
24
31
 
32
+ # @return [Boolean]
25
33
  def invalid?
26
34
  case context
27
35
  when :destroy
28
36
  false
29
37
  else
30
- inner_model.invalid?
38
+ model.invalid?
31
39
  end
32
40
  end
33
41
 
42
+ # @return [Boolean]
34
43
  def valid? = !invalid?
35
44
 
45
+ # Returns a model instance of raw, but it should
46
+ # be noted that application developers are not expected to use this interface.
47
+ #
48
+ # @return [Object] raw model instance
49
+ def __raw_model = model
50
+
36
51
  private
37
52
 
38
- attr_reader :inner_model
53
+ attr_reader :model
39
54
  end
40
55
  end
@@ -6,36 +6,59 @@ module ActiveRecordCompose
6
6
  class InnerModelCollection
7
7
  include Enumerable
8
8
 
9
- def initialize
10
- @inner_models = []
11
- end
12
-
9
+ # Enumerates model objects.
10
+ #
11
+ # @yieldparam [Object] the model instance
12
+ # @return [Enumerator] when not block given.
13
+ # @return [InnerModelCollection] self
13
14
  def each
14
15
  return enum_for(:each) unless block_given?
15
16
 
16
- inner_models.each { yield _1 }
17
+ models.each { yield _1.__raw_model }
18
+ self
19
+ end
20
+
21
+ # Appends model to collection.
22
+ #
23
+ # @param model [Object] the model instance
24
+ # @param context [Symbol] :save or :destroy
25
+ # @return [InnerModelCollection] self
26
+ def <<(model)
27
+ models << wrap(model, context: :save)
17
28
  self
18
29
  end
19
30
 
20
- def <<(inner_model)
21
- inner_models << wrap(inner_model, context: :save)
31
+ # Appends model to collection.
32
+ #
33
+ # @param model [Object] the model instance
34
+ # @return [InnerModelCollection] self
35
+ def push(model, context: :save)
36
+ models << wrap(model, context:)
22
37
  self
23
38
  end
24
39
 
25
- def push(inner_model, context: :save)
26
- inner_models << wrap(inner_model, context:)
40
+ # Enumerates model objects, but it should be noted that
41
+ # application developers are not expected to use this interface.
42
+ #
43
+ # @yieldparam [InnerModel] rawpped model instance.
44
+ # @return [Enumerator] when not block given.
45
+ # @return [InnerModelCollection] self
46
+ def __each_by_wrapped
47
+ return enum_for(:__each_by_wrapped) unless block_given?
48
+
49
+ models.each { yield _1 }
27
50
  self
28
51
  end
29
52
 
30
53
  private
31
54
 
32
- attr_reader :inner_models
55
+ def models = @models ||= []
33
56
 
34
- def wrap(inner_model, context:)
35
- if inner_model.is_a?(ActiveRecordCompose::InnerModel)
36
- inner_model
57
+ def wrap(model, context:)
58
+ if model.is_a?(ActiveRecordCompose::InnerModel)
59
+ model
37
60
  else
38
- ActiveRecordCompose::InnerModel.new(inner_model, context:)
61
+ ActiveRecordCompose::InnerModel.new(model, context:)
39
62
  end
40
63
  end
41
64
  end
@@ -32,6 +32,31 @@ module ActiveRecordCompose
32
32
 
33
33
  def save! = save || raise(error_class_on_save_error.new('Failed to save the model.', self))
34
34
 
35
+ # Behavior is same to `#save`, but `before_create` and `after_create` hooks fires.
36
+ #
37
+ # class ComposedModel < ActiveRecordCompose::Model
38
+ # # ...
39
+ #
40
+ # before_save { puts 'before_save called!' }
41
+ # before_create { puts 'before_create called!' }
42
+ # before_update { puts 'before_update called!' }
43
+ # after_save { puts 'after_save called!' }
44
+ # after_create { puts 'after_create called!' }
45
+ # after_update { puts 'after_update called!' }
46
+ # end
47
+ #
48
+ # model = ComposedModel.new
49
+ #
50
+ # model.save
51
+ # # before_save called!
52
+ # # after_save called!
53
+ #
54
+ # model.create
55
+ # # before_save called!
56
+ # # before_create called!
57
+ # # after_create called!
58
+ # # after_save called!
59
+ #
35
60
  def create(attributes = {})
36
61
  assign_attributes(attributes)
37
62
  return false if invalid?
@@ -39,10 +64,37 @@ module ActiveRecordCompose
39
64
  save_in_transaction { run_callbacks(:save) { run_callbacks(:create) { save_models } } }
40
65
  end
41
66
 
67
+ # Behavior is same to `#create`, but raises an exception prematurely on failure.
68
+ #
42
69
  def create!(attributes = {})
43
70
  create(attributes) || raise(error_class_on_save_error.new('Failed to create the model.', self))
44
71
  end
45
72
 
73
+ # Behavior is same to `#save`, but `before_update` and `after_update` hooks fires.
74
+ #
75
+ # class ComposedModel < ActiveRecordCompose::Model
76
+ # # ...
77
+ #
78
+ # before_save { puts 'before_save called!' }
79
+ # before_create { puts 'before_create called!' }
80
+ # before_update { puts 'before_update called!' }
81
+ # after_save { puts 'after_save called!' }
82
+ # after_create { puts 'after_create called!' }
83
+ # after_update { puts 'after_update called!' }
84
+ # end
85
+ #
86
+ # model = ComposedModel.new
87
+ #
88
+ # model.save
89
+ # # before_save called!
90
+ # # after_save called!
91
+ #
92
+ # model.update
93
+ # # before_save called!
94
+ # # before_update called!
95
+ # # after_update called!
96
+ # # after_save called!
97
+ #
46
98
  def update(attributes = {})
47
99
  assign_attributes(attributes)
48
100
  return false if invalid?
@@ -50,6 +102,8 @@ module ActiveRecordCompose
50
102
  save_in_transaction { run_callbacks(:save) { run_callbacks(:update) { save_models } } }
51
103
  end
52
104
 
105
+ # Behavior is same to `#update`, but raises an exception prematurely on failure.
106
+ #
53
107
  def update!(attributes = {})
54
108
  update(attributes) || raise(error_class_on_save_error.new('Failed to update the model.', self))
55
109
  end
@@ -58,7 +112,9 @@ module ActiveRecordCompose
58
112
 
59
113
  def models = @models ||= ActiveRecordCompose::InnerModelCollection.new
60
114
 
61
- def validate_models = models.select { _1.invalid? }.each { errors.merge!(_1) }
115
+ def wrapped_models = models.__each_by_wrapped
116
+
117
+ def validate_models = wrapped_models.select { _1.invalid? }.each { errors.merge!(_1) }
62
118
 
63
119
  def save_in_transaction
64
120
  run_callbacks(:commit) do
@@ -74,6 +130,6 @@ module ActiveRecordCompose
74
130
  end.present?
75
131
  end
76
132
 
77
- def save_models = models.all? { _1.save! }
133
+ def save_models = wrapped_models.all? { _1.save! }
78
134
  end
79
135
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecordCompose
4
- VERSION = '0.1.0'
4
+ VERSION = '0.1.1'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record_compose
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - hamajyotan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-06 00:00:00.000000000 Z
11
+ date: 2024-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -49,6 +49,8 @@ homepage: https://github.com/active_record_compose
49
49
  licenses:
50
50
  - MIT
51
51
  metadata:
52
+ changelog_uri: https://github.com/hamajyotan/active_record_compose/blob/main/CHANGELOG.md
53
+ source_code_uri: https://github.com/hamajyotan/active_record_compose
52
54
  rubygems_mfa_required: 'true'
53
55
  post_install_message:
54
56
  rdoc_options: []