active_record_compose 1.1.0 → 1.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 +4 -4
- data/.yardopts +2 -0
- data/CHANGELOG.md +16 -0
- data/lib/active_record_compose/attributes.rb +63 -55
- data/lib/active_record_compose/callbacks.rb +30 -2
- data/lib/active_record_compose/composed_collection.rb +35 -8
- data/lib/active_record_compose/exceptions.rb +29 -0
- data/lib/active_record_compose/inspectable.rb +58 -16
- data/lib/active_record_compose/model.rb +0 -313
- data/lib/active_record_compose/persistence.rb +61 -13
- data/lib/active_record_compose/transaction_support.rb +36 -12
- data/lib/active_record_compose/validations.rb +73 -1
- data/lib/active_record_compose/version.rb +1 -1
- data/lib/active_record_compose/wrapped_model.rb +13 -4
- data/lib/active_record_compose.rb +1 -0
- data/sig/_internal/package_private.rbs +20 -43
- data/sig/active_record_compose.rbs +8 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2622aa32a886a2c21fcc7836254285cb92f1ce7745674297c3e7fe46bcbe556a
|
|
4
|
+
data.tar.gz: 747acd3e97cb78aba78b9d3f2c87ab4d9bd34b0727aaf2a1c94d9520ea9eaa08
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e6002732e8e6fa09269ccb4a7635af4ef683d06af14e829aa062846c6dbb90c2942d5b3cc2b4d715eeef2182498e732d33b5ae004836ff703f8d8235fec12c70
|
|
7
|
+
data.tar.gz: 18d3f9a635d3f4bf940eeb4020824fa7fc7d91cf27b0a99aa253af53e31fdca6bebd69d402537bea29749de26eba3f5a261e10a3ef2ebf079294e7fc3dbd5127
|
data/.yardopts
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [1.2.0] - 2026-01-05
|
|
4
|
+
|
|
5
|
+
* Avoid issuing multiple saves on the same object.
|
|
6
|
+
(https://github.com/hamajyotan/active_record_compose/pull/56)
|
|
7
|
+
* The storage of `#models` has been changed from an Array to a Set.
|
|
8
|
+
This prevents duplicate additions of the same object and option combinations.
|
|
9
|
+
Also, `#models#delete` now deletes the model regardless of the options used when it was added.
|
|
10
|
+
(https://github.com/hamajyotan/active_record_compose/pull/57)
|
|
11
|
+
* Adding an `ActiveRecordCompose::Model` to `#models` now throws an error if there is a circular reference.
|
|
12
|
+
(https://github.com/hamajyotan/active_record_compose/pull/58)
|
|
13
|
+
|
|
14
|
+
## [1.1.1] - 2025-12-04
|
|
15
|
+
|
|
16
|
+
* fix: the save method would return nil instead of false.
|
|
17
|
+
* doc: We've simplified the documentation comment yard.
|
|
18
|
+
|
|
3
19
|
## [1.1.0] - 2025-11-19
|
|
4
20
|
|
|
5
21
|
* Implemented ActiveRecord-like #inspect
|
|
@@ -5,8 +5,6 @@ require_relative "attributes/delegation"
|
|
|
5
5
|
require_relative "attributes/querying"
|
|
6
6
|
|
|
7
7
|
module ActiveRecordCompose
|
|
8
|
-
# @private
|
|
9
|
-
#
|
|
10
8
|
# Provides attribute-related functionality for use within ActiveRecordCompose::Model.
|
|
11
9
|
#
|
|
12
10
|
# This module allows you to define attributes on your composed model, including support
|
|
@@ -56,45 +54,32 @@ module ActiveRecordCompose
|
|
|
56
54
|
include ActiveModel::Attributes
|
|
57
55
|
|
|
58
56
|
included do
|
|
57
|
+
# @type self: Class
|
|
58
|
+
|
|
59
59
|
include Querying
|
|
60
60
|
|
|
61
|
-
# @type self: Class
|
|
62
61
|
class_attribute :delegated_attributes, instance_writer: false
|
|
63
62
|
end
|
|
64
63
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
#
|
|
69
|
-
# class AccountRegistration < ActiveRecordCompose::Model
|
|
70
|
-
# def initialize(account, attributes = {})
|
|
71
|
-
# @account = account
|
|
72
|
-
# super(attributes)
|
|
73
|
-
# models.push(account)
|
|
74
|
-
# end
|
|
75
|
-
#
|
|
76
|
-
# attribute :original_attribute, :string, default: "qux"
|
|
77
|
-
# delegate_attribute :name, to: :account
|
|
78
|
-
#
|
|
79
|
-
# private
|
|
80
|
-
#
|
|
81
|
-
# attr_reader :account
|
|
82
|
-
# end
|
|
83
|
-
#
|
|
84
|
-
# account = Account.new
|
|
85
|
-
# account.name = "foo"
|
|
86
|
-
#
|
|
87
|
-
# registration = AccountRegistration.new(account)
|
|
88
|
-
# registration.name # => "foo" (delegated)
|
|
89
|
-
# registration.name? # => true (delegated attribute method + `?`)
|
|
90
|
-
#
|
|
91
|
-
# registration.name = "bar" # => updates account.name
|
|
92
|
-
# account.name # => "bar"
|
|
93
|
-
# account.name? # => true
|
|
64
|
+
# steep:ignore:start
|
|
65
|
+
|
|
66
|
+
class_methods do
|
|
67
|
+
# Provides a method of attribute access to the encapsulated model.
|
|
94
68
|
#
|
|
95
|
-
#
|
|
96
|
-
#
|
|
69
|
+
# It provides a way to access the attributes of the model it encompasses,
|
|
70
|
+
# allowing transparent access as if it had those attributes itself.
|
|
97
71
|
#
|
|
72
|
+
# @param [Array<Symbol, String>] attributes
|
|
73
|
+
# attributes A variable-length list of attribute names to delegate.
|
|
74
|
+
# @param [Symbol, String] to
|
|
75
|
+
# The target object to which attributes are delegated (keyword argument).
|
|
76
|
+
# @param [Boolean] allow_nil
|
|
77
|
+
# allow_nil Whether to allow nil values. Defaults to false.
|
|
78
|
+
# @example Basic usage
|
|
79
|
+
# delegate_attribute :name, :email, to: :profile
|
|
80
|
+
# @example Allowing nil
|
|
81
|
+
# delegate_attribute :bio, to: :profile, allow_nil: true
|
|
82
|
+
# @see Module#delegate for similar behavior in ActiveSupport
|
|
98
83
|
def delegate_attribute(*attributes, to:, allow_nil: false)
|
|
99
84
|
if to.start_with?("@")
|
|
100
85
|
raise ArgumentError, "Instance variables cannot be specified in delegate to. (#{to})"
|
|
@@ -107,45 +92,68 @@ module ActiveRecordCompose
|
|
|
107
92
|
end
|
|
108
93
|
|
|
109
94
|
# Returns a array of attribute name.
|
|
110
|
-
# Attributes declared with
|
|
95
|
+
# Attributes declared with {.delegate_attribute} are also merged.
|
|
111
96
|
#
|
|
97
|
+
# @see #attribute_names
|
|
112
98
|
# @return [Array<String>] array of attribute name.
|
|
113
99
|
def attribute_names = super + delegated_attributes.to_a.map { _1.attribute_name }
|
|
114
100
|
end
|
|
115
101
|
|
|
102
|
+
# steep:ignore:end
|
|
103
|
+
|
|
116
104
|
# Returns a array of attribute name.
|
|
117
|
-
# Attributes declared with
|
|
105
|
+
# Attributes declared with {.delegate_attribute} are also merged.
|
|
106
|
+
#
|
|
107
|
+
# class Foo < ActiveRecordCompose::Base
|
|
108
|
+
# def initialize(attributes = {})
|
|
109
|
+
# @account = Account.new
|
|
110
|
+
# super
|
|
111
|
+
# end
|
|
112
|
+
#
|
|
113
|
+
# attribute :confirmation, :boolean, default: false # plain attribute
|
|
114
|
+
# delegate_attribute :name, to: :account # delegated attribute
|
|
115
|
+
#
|
|
116
|
+
# private
|
|
117
|
+
#
|
|
118
|
+
# attr_reader :account
|
|
119
|
+
# end
|
|
118
120
|
#
|
|
121
|
+
# Foo.attribute_names # Returns the merged state of plain and delegated attributes
|
|
122
|
+
# # => ["confirmation" ,"name"]
|
|
123
|
+
#
|
|
124
|
+
# foo = Foo.new
|
|
125
|
+
# foo.attribute_names # Similar behavior for instance method version
|
|
126
|
+
# # => ["confirmation", "name"]
|
|
127
|
+
#
|
|
128
|
+
# @see #attributes
|
|
119
129
|
# @return [Array<String>] array of attribute name.
|
|
120
130
|
def attribute_names = super + delegated_attributes.to_a.map { _1.attribute_name }
|
|
121
131
|
|
|
122
132
|
# Returns a hash with the attribute name as key and the attribute value as value.
|
|
123
|
-
# Attributes declared with
|
|
133
|
+
# Attributes declared with {.delegate_attribute} are also merged.
|
|
124
134
|
#
|
|
125
|
-
#
|
|
126
|
-
#
|
|
127
|
-
#
|
|
128
|
-
#
|
|
129
|
-
#
|
|
130
|
-
# super(attributes)
|
|
131
|
-
# models.push(account)
|
|
132
|
-
# end
|
|
135
|
+
# class Foo < ActiveRecordCompose::Base
|
|
136
|
+
# def initialize(attributes = {})
|
|
137
|
+
# @account = Account.new
|
|
138
|
+
# super
|
|
139
|
+
# end
|
|
133
140
|
#
|
|
134
|
-
#
|
|
135
|
-
#
|
|
141
|
+
# attribute :confirmation, :boolean, default: false # plain attribute
|
|
142
|
+
# delegate_attribute :name, to: :account # delegated attribute
|
|
136
143
|
#
|
|
137
|
-
#
|
|
144
|
+
# private
|
|
138
145
|
#
|
|
139
|
-
#
|
|
140
|
-
#
|
|
141
|
-
#
|
|
142
|
-
# account = Account.new
|
|
143
|
-
# account.name = "foo"
|
|
146
|
+
# attr_reader :account
|
|
147
|
+
# end
|
|
144
148
|
#
|
|
145
|
-
#
|
|
149
|
+
# foo = Foo.new
|
|
150
|
+
# foo.name = "Alice"
|
|
151
|
+
# foo.confirmation = true
|
|
146
152
|
#
|
|
147
|
-
#
|
|
153
|
+
# foo.attributes # Returns the merged state of plain and delegated attributes
|
|
154
|
+
# # => { "confirmation" => true, "name" => "Alice" }
|
|
148
155
|
#
|
|
156
|
+
# @return [Hash<String, Object>] hash with the attribute name as key and the attribute value as value.
|
|
149
157
|
def attributes
|
|
150
158
|
super.merge(*delegated_attributes.to_a.map { _1.attribute_hash(self) })
|
|
151
159
|
end
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module ActiveRecordCompose
|
|
4
|
-
# @private
|
|
5
|
-
#
|
|
6
4
|
# Provides hooks into the life cycle of an ActiveRecordCompose model,
|
|
7
5
|
# allowing you to insert custom logic before or after changes to the object's state.
|
|
8
6
|
#
|
|
@@ -21,18 +19,48 @@ module ActiveRecordCompose
|
|
|
21
19
|
include ActiveModel::Validations::Callbacks
|
|
22
20
|
|
|
23
21
|
included do
|
|
22
|
+
# @!method self.before_save(*args, &block)
|
|
23
|
+
# Registers a callback to be called before a model is saved.
|
|
24
|
+
|
|
25
|
+
# @!method self.around_save(*args, &block)
|
|
26
|
+
# Registers a callback to be called around the save of a model.
|
|
27
|
+
|
|
28
|
+
# @!method self.after_save(*args, &block)
|
|
29
|
+
# Registers a callback to be called after a model is saved.
|
|
30
|
+
|
|
24
31
|
define_model_callbacks :save
|
|
32
|
+
|
|
33
|
+
# @!method self.before_create(*args, &block)
|
|
34
|
+
# Registers a callback to be called before a model is created.
|
|
35
|
+
|
|
36
|
+
# @!method self.around_create(*args, &block)
|
|
37
|
+
# Registers a callback to be called around the creation of a model.
|
|
38
|
+
|
|
39
|
+
# @!method self.after_create(*args, &block)
|
|
40
|
+
# Registers a callback to be called after a model is created.
|
|
41
|
+
|
|
25
42
|
define_model_callbacks :create
|
|
43
|
+
|
|
44
|
+
# @!method self.before_update(*args, &block)
|
|
45
|
+
# Registers a callback to be called before a model is updated.
|
|
46
|
+
|
|
47
|
+
# @!method self.around_update(*args, &block)
|
|
48
|
+
# Registers a callback to be called around the update of a model.
|
|
49
|
+
|
|
50
|
+
# @!method self.after_update(*args, &block)
|
|
51
|
+
# Registers a callback to be called after a update is updated.
|
|
26
52
|
define_model_callbacks :update
|
|
27
53
|
end
|
|
28
54
|
|
|
29
55
|
private
|
|
30
56
|
|
|
57
|
+
# @private
|
|
31
58
|
# Evaluate while firing callbacks such as `before_save` `after_save`
|
|
32
59
|
# before and after block evaluation.
|
|
33
60
|
#
|
|
34
61
|
def with_callbacks(&block) = run_callbacks(:save) { run_callbacks(callback_context, &block) }
|
|
35
62
|
|
|
63
|
+
# @private
|
|
36
64
|
# Returns the symbol representing the callback context, which is `:create` if the record
|
|
37
65
|
# is new, or `:update` if it has been persisted.
|
|
38
66
|
#
|
|
@@ -13,7 +13,7 @@ module ActiveRecordCompose
|
|
|
13
13
|
|
|
14
14
|
def initialize(owner)
|
|
15
15
|
@owner = owner
|
|
16
|
-
@models =
|
|
16
|
+
@models = Set.new
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
# Enumerates model objects.
|
|
@@ -69,13 +69,28 @@ module ActiveRecordCompose
|
|
|
69
69
|
# Removes the specified model from the collection.
|
|
70
70
|
# Returns nil if the deletion fails, self if it succeeds.
|
|
71
71
|
#
|
|
72
|
+
# The specified model instance will be deleted regardless of the options used when it was added.
|
|
73
|
+
#
|
|
74
|
+
# @example
|
|
75
|
+
# model_a = Model.new
|
|
76
|
+
# model_b = Model.new
|
|
77
|
+
#
|
|
78
|
+
# collection.push(model_a, destroy: true)
|
|
79
|
+
# collection.push(model_b)
|
|
80
|
+
# collection.push(model_a, destroy: false)
|
|
81
|
+
# collection.count #=> 3
|
|
82
|
+
#
|
|
83
|
+
# collection.delete(model_a)
|
|
84
|
+
# collection.count #=> 1
|
|
85
|
+
#
|
|
72
86
|
# @param model [Object] model instance
|
|
73
87
|
# @return [self] Successful deletion
|
|
74
88
|
# @return [nil] If deletion fails
|
|
75
89
|
def delete(model)
|
|
76
|
-
|
|
77
|
-
return nil
|
|
90
|
+
matched = models.select { _1.__raw_model == model }
|
|
91
|
+
return nil if matched.blank?
|
|
78
92
|
|
|
93
|
+
matched.each { models.delete(_1) }
|
|
79
94
|
self
|
|
80
95
|
end
|
|
81
96
|
|
|
@@ -87,17 +102,27 @@ module ActiveRecordCompose
|
|
|
87
102
|
# @private
|
|
88
103
|
def wrap(model, destroy: false, if: nil)
|
|
89
104
|
if destroy.is_a?(Symbol)
|
|
90
|
-
|
|
91
|
-
destroy = -> { owner.__send__(method) }
|
|
105
|
+
destroy = symbol_proc_map[destroy]
|
|
92
106
|
end
|
|
107
|
+
|
|
93
108
|
if_option = binding.local_variable_get(:if)
|
|
94
109
|
if if_option.is_a?(Symbol)
|
|
95
|
-
|
|
96
|
-
if_option = -> { owner.__send__(method) }
|
|
110
|
+
if_option = symbol_proc_map[if_option]
|
|
97
111
|
end
|
|
112
|
+
|
|
98
113
|
ActiveRecordCompose::WrappedModel.new(model, destroy:, if: if_option)
|
|
99
114
|
end
|
|
100
115
|
|
|
116
|
+
# @private
|
|
117
|
+
def symbol_proc_map
|
|
118
|
+
@symbol_proc_map ||=
|
|
119
|
+
Hash.new do |h, k|
|
|
120
|
+
h[k] = -> { owner.__send__(k) }
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def instance_variables_to_inspect = %i[@owner @models]
|
|
125
|
+
|
|
101
126
|
# @private
|
|
102
127
|
module PackagePrivate
|
|
103
128
|
refine ComposedCollection do
|
|
@@ -105,7 +130,9 @@ module ActiveRecordCompose
|
|
|
105
130
|
#
|
|
106
131
|
# @private
|
|
107
132
|
# @return [Array[WrappedModel]] array of wrapped model instance.
|
|
108
|
-
def __wrapped_models
|
|
133
|
+
def __wrapped_models
|
|
134
|
+
models.reject { _1.ignore? }.uniq { [ _1.__raw_model, !!_1.destroy_context? ] }.select { _1.__raw_model }
|
|
135
|
+
end
|
|
109
136
|
end
|
|
110
137
|
end
|
|
111
138
|
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveRecordCompose
|
|
4
|
+
# Occurs when a circular reference is detected in the containing model.
|
|
5
|
+
#
|
|
6
|
+
# @example
|
|
7
|
+
# class Model < ActiveRecordCompose::Model
|
|
8
|
+
# def initialize
|
|
9
|
+
# super()
|
|
10
|
+
# models << self # Adding itself to models creates a circular reference.
|
|
11
|
+
# end
|
|
12
|
+
# end
|
|
13
|
+
# model = Model.new
|
|
14
|
+
# model.save #=> raises ActiveRecordCompose::CircularReferenceDetected
|
|
15
|
+
#
|
|
16
|
+
# @example
|
|
17
|
+
# class Model < ActiveRecordCompose::Model
|
|
18
|
+
# attribute :model
|
|
19
|
+
# before_validation { models << model }
|
|
20
|
+
# end
|
|
21
|
+
# inner = Model.new
|
|
22
|
+
# middle = Model.new(model: inner)
|
|
23
|
+
# outer = Model.new(model: middle)
|
|
24
|
+
#
|
|
25
|
+
# inner.model = outer # There is a circular reference in the form outer > middle > inner > outer.
|
|
26
|
+
# outer.save #=> raises ActiveRecordCompose::CircularReferenceDetected
|
|
27
|
+
#
|
|
28
|
+
class CircularReferenceDetected < StandardError; end
|
|
29
|
+
end
|
|
@@ -4,8 +4,6 @@ require "active_support/parameter_filter"
|
|
|
4
4
|
require_relative "attributes"
|
|
5
5
|
|
|
6
6
|
module ActiveRecordCompose
|
|
7
|
-
# @private
|
|
8
|
-
#
|
|
9
7
|
# It provides #inspect behavior.
|
|
10
8
|
# It tries to replicate the inspect format provided by ActiveRecord as closely as possible.
|
|
11
9
|
#
|
|
@@ -39,26 +37,48 @@ module ActiveRecordCompose
|
|
|
39
37
|
extend ActiveSupport::Concern
|
|
40
38
|
include ActiveRecordCompose::Attributes
|
|
41
39
|
|
|
40
|
+
# steep:ignore:start
|
|
41
|
+
|
|
42
|
+
# @private
|
|
43
|
+
FILTERED_MASK =
|
|
44
|
+
Class.new(DelegateClass(::String)) do
|
|
45
|
+
def pretty_print(pp)
|
|
46
|
+
pp.text __getobj__
|
|
47
|
+
end
|
|
48
|
+
end.new(ActiveSupport::ParameterFilter::FILTERED).freeze
|
|
49
|
+
private_constant :FILTERED_MASK
|
|
50
|
+
|
|
51
|
+
# steep:ignore:end
|
|
52
|
+
|
|
42
53
|
included do
|
|
43
54
|
self.filter_attributes = []
|
|
44
55
|
end
|
|
45
56
|
|
|
46
|
-
|
|
57
|
+
# steep:ignore:start
|
|
58
|
+
|
|
59
|
+
class_methods do
|
|
60
|
+
# Returns columns not to expose when invoking {#inspect}.
|
|
61
|
+
#
|
|
62
|
+
# @return [Array<Symbol>]
|
|
63
|
+
# @see #inspect
|
|
47
64
|
def filter_attributes
|
|
48
65
|
if @filter_attributes.nil?
|
|
49
|
-
superclass.filter_attributes
|
|
66
|
+
superclass.filter_attributes
|
|
50
67
|
else
|
|
51
68
|
@filter_attributes
|
|
52
69
|
end
|
|
53
70
|
end
|
|
54
71
|
|
|
72
|
+
# Specify columns not to expose when invoking {#inspect}.
|
|
73
|
+
#
|
|
74
|
+
# @param [Array<Symbol>] value
|
|
75
|
+
# @see #inspect
|
|
55
76
|
def filter_attributes=(value)
|
|
56
77
|
@inspection_filter = nil
|
|
57
78
|
@filter_attributes = value
|
|
58
79
|
end
|
|
59
80
|
|
|
60
|
-
#
|
|
61
|
-
|
|
81
|
+
# @private
|
|
62
82
|
def inspection_filter
|
|
63
83
|
if @filter_attributes.nil?
|
|
64
84
|
superclass.inspection_filter
|
|
@@ -77,20 +97,41 @@ module ActiveRecordCompose
|
|
|
77
97
|
@filter_attributes ||= nil
|
|
78
98
|
end
|
|
79
99
|
end
|
|
80
|
-
|
|
81
|
-
FILTERED_MASK =
|
|
82
|
-
Class.new(DelegateClass(::String)) do
|
|
83
|
-
def pretty_print(pp)
|
|
84
|
-
pp.text __getobj__
|
|
85
|
-
end
|
|
86
|
-
end.new(ActiveSupport::ParameterFilter::FILTERED).freeze
|
|
87
|
-
private_constant :FILTERED_MASK
|
|
88
|
-
|
|
89
|
-
# steep:ignore:end
|
|
90
100
|
end
|
|
91
101
|
|
|
102
|
+
# steep:ignore:end
|
|
103
|
+
|
|
92
104
|
# Returns a formatted string representation of the record's attributes.
|
|
105
|
+
# It tries to replicate the inspect format provided by ActiveRecord as closely as possible.
|
|
106
|
+
#
|
|
107
|
+
# @example
|
|
108
|
+
# class Model < ActiveRecordCompose::Model
|
|
109
|
+
# def initialize(ar_model)
|
|
110
|
+
# @ar_model = ar_model
|
|
111
|
+
# super
|
|
112
|
+
# end
|
|
113
|
+
#
|
|
114
|
+
# attribute :foo, :date, default: -> { Date.today }
|
|
115
|
+
# delegate_attribute :bar, to: :ar_model
|
|
116
|
+
#
|
|
117
|
+
# private attr_reader :ar_model
|
|
118
|
+
# end
|
|
119
|
+
#
|
|
120
|
+
# m = Model.new(ar_model)
|
|
121
|
+
# m.inspect #=> #<Model:0x00007ff0fe75fe58 foo: "2025-11-14", bar: "bar">
|
|
122
|
+
#
|
|
123
|
+
# @example use {.filter_attributes}
|
|
124
|
+
# class Model < ActiveRecordCompose::Model
|
|
125
|
+
# self.filter_attributes += %i[foo]
|
|
126
|
+
#
|
|
127
|
+
# # ...
|
|
128
|
+
# end
|
|
129
|
+
#
|
|
130
|
+
# m = Model.new(ar_model)
|
|
131
|
+
# m.inspect #=> #<Model:0x00007ff0fe75fe58 foo: [FILTERED], bar: "bar">
|
|
93
132
|
#
|
|
133
|
+
# @return [String] formatted string representation of the record's attributes.
|
|
134
|
+
# @see .filter_attributes
|
|
94
135
|
def inspect
|
|
95
136
|
inspection =
|
|
96
137
|
if @attributes
|
|
@@ -126,6 +167,7 @@ module ActiveRecordCompose
|
|
|
126
167
|
|
|
127
168
|
private
|
|
128
169
|
|
|
170
|
+
# @private
|
|
129
171
|
def format_for_inspect(name, value)
|
|
130
172
|
return value.inspect if value.nil?
|
|
131
173
|
|