active_record_compose 0.1.0 → 0.1.1
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 +7 -1
- data/README.md +1 -1
- data/lib/active_record_compose/delegate_attribute.rb +33 -0
- data/lib/active_record_compose/inner_model.rb +23 -8
- data/lib/active_record_compose/inner_model_collection.rb +37 -14
- data/lib/active_record_compose/model.rb +58 -2
- data/lib/active_record_compose/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b6881ca78dfbf9fc5fc15cf72ac6073c4780d4b7b32747fc1b58a0147adce3fe
|
4
|
+
data.tar.gz: 37a7dfa3d4de10d2a35ea6a10a9d3e131809eba27ef60cb5b917b1b736f209e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: abc371fd146961cec4f4b8d234367734e772aaab9b08450debb1a79adba4fa5703fd169090d1d636c95f56a89ec0184e5c7db2f4bb04f61609dc925e5fe08ffa
|
7
|
+
data.tar.gz: 427c2bd3151f1fba2541795aa36f645952a87930ccd92fb0d1d7a9a1144d7486c30180cd0b021c1660aab380dd1cb887191fe37c1dc069b0d3cd5197f7c3ace0
|
data/CHANGELOG.md
CHANGED
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
|
-
|
6
|
-
|
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: :
|
14
|
+
delegate :errors, to: :model
|
11
15
|
|
16
|
+
# @return [Symbol] :save or :destroy
|
12
17
|
def context
|
13
|
-
@context.respond_to?(:call) ? @context.call(
|
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
|
-
|
26
|
+
model.destroy!
|
20
27
|
else
|
21
|
-
|
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
|
-
|
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 :
|
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
|
-
|
10
|
-
|
11
|
-
|
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
|
-
|
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
|
-
|
21
|
-
|
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
|
-
|
26
|
-
|
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
|
-
|
55
|
+
def models = @models ||= []
|
33
56
|
|
34
|
-
def wrap(
|
35
|
-
if
|
36
|
-
|
57
|
+
def wrap(model, context:)
|
58
|
+
if model.is_a?(ActiveRecordCompose::InnerModel)
|
59
|
+
model
|
37
60
|
else
|
38
|
-
ActiveRecordCompose::InnerModel.new(
|
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
|
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 =
|
133
|
+
def save_models = wrapped_models.all? { _1.save! }
|
78
134
|
end
|
79
135
|
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.
|
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-
|
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: []
|