acts_as_table 0.0.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.
Files changed (34) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +1 -0
  3. data/LICENSE +30 -0
  4. data/README.md +256 -0
  5. data/Rakefile +13 -0
  6. data/app/models/acts_as_table/belongs_to.rb +81 -0
  7. data/app/models/acts_as_table/column_model.rb +89 -0
  8. data/app/models/acts_as_table/foreign_key.rb +299 -0
  9. data/app/models/acts_as_table/foreign_key_map.rb +121 -0
  10. data/app/models/acts_as_table/has_many.rb +90 -0
  11. data/app/models/acts_as_table/has_many_target.rb +40 -0
  12. data/app/models/acts_as_table/lense.rb +131 -0
  13. data/app/models/acts_as_table/primary_key.rb +108 -0
  14. data/app/models/acts_as_table/record.rb +109 -0
  15. data/app/models/acts_as_table/record_error.rb +50 -0
  16. data/app/models/acts_as_table/record_model.rb +194 -0
  17. data/app/models/acts_as_table/row_model.rb +285 -0
  18. data/app/models/acts_as_table/table.rb +41 -0
  19. data/app/models/acts_as_table/value.rb +80 -0
  20. data/app/models/concerns/acts_as_table/record_model_class_methods.rb +554 -0
  21. data/app/models/concerns/acts_as_table/value_provider.rb +223 -0
  22. data/app/models/concerns/acts_as_table/value_provider_association_methods.rb +57 -0
  23. data/config/locales/en.yml +8 -0
  24. data/db/migrate/1_acts_as_table_migration.rb +186 -0
  25. data/lib/acts_as_table.rb +288 -0
  26. data/lib/acts_as_table/adapter.rb +81 -0
  27. data/lib/acts_as_table/engine.rb +14 -0
  28. data/lib/acts_as_table/headers.rb +196 -0
  29. data/lib/acts_as_table/mapper.rb +464 -0
  30. data/lib/acts_as_table/path.rb +157 -0
  31. data/lib/acts_as_table/reader.rb +149 -0
  32. data/lib/acts_as_table/version.rb +4 -0
  33. data/lib/acts_as_table/writer.rb +116 -0
  34. metadata +181 -0
@@ -0,0 +1,40 @@
1
+ module ActsAsTable
2
+ # ActsAsTable collection macro association target.
3
+ #
4
+ # @!attribute [rw] position
5
+ # Returns the position of this ActsAsTable collection macro association target.
6
+ #
7
+ # @return [Integer]
8
+ class HasManyTarget < ::ActiveRecord::Base
9
+ # @!parse
10
+ # include ActsAsTable::ValueProvider
11
+ # include ActsAsTable::ValueProviderAssociationMethods
12
+
13
+ self.table_name = ActsAsTable.has_many_targets_table
14
+
15
+ # Returns the ActsAsTable collection macro association for this target.
16
+ belongs_to :has_many, **{
17
+ class_name: 'ActsAsTable::HasMany',
18
+ inverse_of: :has_many_targets,
19
+ required: true,
20
+ }
21
+
22
+ # Returns the ActsAsTable record model for this ActsAsTable collection macro association target.
23
+ belongs_to :record_model, **{
24
+ class_name: 'ActsAsTable::RecordModel',
25
+ inverse_of: :has_many_targets,
26
+ required: true,
27
+ }
28
+
29
+ validates :position, **{
30
+ numericality: {
31
+ greater_than_or_equal_to: 1,
32
+ only_integer: true,
33
+ },
34
+ presence: true,
35
+ uniqueness: {
36
+ scope: ['has_many_id'],
37
+ },
38
+ }
39
+ end
40
+ end
@@ -0,0 +1,131 @@
1
+ module ActsAsTable
2
+ # ActsAsTable attribute accessor (value provider).
3
+ #
4
+ # @note The name "Lense" was selected for 2 reasons: similarity of behavior of this class and the corresponding type(s) in the Haskell package, [lens](https://hackage.haskell.org/package/lens); and that "Attribute" is not allowed as a Ruby on Rails model class name (because the corresponding table name would be "attributes", which would conflict with {ActiveRecord::AttributeMethods#attributes}).
5
+ #
6
+ # @!attribute [rw] default_value
7
+ # Returns the default value for this ActsAsTable attribute accessor.
8
+ #
9
+ # @return [String, nil]
10
+ # @!attribute [rw] method_name
11
+ # Returns the method name for this ActsAsTable attribute accessor (an `attr_reader` or a Ruby on Rails model column name).
12
+ #
13
+ # @return [String]
14
+ class Lense < ::ActiveRecord::Base
15
+ # @!parse
16
+ # include ActsAsTable::ValueProvider
17
+ # include ActsAsTable::ValueProvider::InstanceMethods
18
+ # include ActsAsTable::ValueProviderAssociationMethods
19
+
20
+ self.table_name = ActsAsTable.lenses_table
21
+
22
+ acts_as_table_value_provider
23
+
24
+ # Returns the ActsAsTable column model for this ActsAsTable attribute accessor or `nil`.
25
+ #
26
+ # @return [ActsAsTable::ColumnModel, nil]
27
+ belongs_to :column_model, **{
28
+ class_name: 'ActsAsTable::ColumnModel',
29
+ inverse_of: :lenses,
30
+ required: false,
31
+ }
32
+
33
+ # Returns the ActsAsTable record model for this ActsAsTable attribute accessor.
34
+ belongs_to :record_model, **{
35
+ class_name: 'ActsAsTable::RecordModel',
36
+ inverse_of: :lenses,
37
+ required: true,
38
+ }
39
+
40
+ # Returns the ActsAsTable values that have been provided by this ActsAsTable attribute accessor.
41
+ has_many :values, **{
42
+ as: :value_provider,
43
+ class_name: 'ActsAsTable::Value',
44
+ dependent: :restrict_with_exception,
45
+ foreign_key: 'value_provider_id',
46
+ foreign_type: 'value_provider_type',
47
+ inverse_of: :value_provider,
48
+ }
49
+
50
+ validates :default_value, **{
51
+ presence: {
52
+ unless: :column_model,
53
+ },
54
+ }
55
+
56
+ validates :method_name, **{
57
+ presence: true,
58
+ }
59
+
60
+ validate :record_model_class_must_respond_to_method_name, **{
61
+ if: ::Proc.new { |lense| lense.method_name.present? },
62
+ }
63
+
64
+ protected
65
+
66
+ # @param [ActiveRecord::Base, nil] base
67
+ # @return [Object, nil]
68
+ def _get_value(base = nil)
69
+ if base.nil?
70
+ nil
71
+ else
72
+ base.send(:"#{self.method_name}")
73
+ end
74
+ end
75
+
76
+ # @param [ActiveRecord::Base, nil] base
77
+ # @param [Object, nil] new_value
78
+ # @return [Array<Object>]
79
+ def _set_value(base = nil, new_value = nil)
80
+ if base.nil?
81
+ [
82
+ nil,
83
+ false,
84
+ ]
85
+ else
86
+ # @return [Object, nil]
87
+ orig_value = _get_value(base)
88
+
89
+ # @return [Boolean]
90
+ changed = !self.column_model.nil? && !(orig_value.nil? ? new_value.nil? : (new_value.nil? ? false : orig_value.to_s.eql?(new_value.to_s)))
91
+
92
+ [
93
+ base.send(:"#{self.method_name}=", new_value),
94
+ changed,
95
+ ]
96
+ end
97
+ end
98
+
99
+ private
100
+
101
+ # @param [Class] klass
102
+ # @param [String] attribute_name
103
+ # @return [Boolean]
104
+ def _attr_accessor?(klass, attribute_name)
105
+ [
106
+ :"#{attribute_name}",
107
+ :"#{attribute_name}=",
108
+ ].all? { |sym|
109
+ klass.instance_methods.include?(sym)
110
+ }
111
+ end
112
+
113
+ # @param [Class] klass
114
+ # @param [String] column_name
115
+ # @return [Boolean]
116
+ def _column?(klass, column_name)
117
+ klass.column_names.include?(column_name.to_s)
118
+ end
119
+
120
+ # @return [void]
121
+ def record_model_class_must_respond_to_method_name
122
+ self.record_model.try { |record_model| record_model.class_name.constantize rescue nil }.try { |klass|
123
+ unless _attr_accessor?(klass, self.method_name) || _column?(klass, self.method_name)
124
+ self.errors.add('method_name', :required)
125
+ end
126
+ }
127
+
128
+ return
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,108 @@
1
+ module ActsAsTable
2
+ # ActsAsTable primary key (value provider).
3
+ #
4
+ # @!attribute [rw] method_name
5
+ # Returns the method name for this ActsAsTable primary key (a Ruby on Rails model column name).
6
+ #
7
+ # @return [String]
8
+ class PrimaryKey < ::ActiveRecord::Base
9
+ # @!parse
10
+ # include ActsAsTable::ValueProvider
11
+ # include ActsAsTable::ValueProvider::InstanceMethods
12
+ # include ActsAsTable::ValueProviderAssociationMethods
13
+
14
+ self.table_name = ActsAsTable.primary_keys_table
15
+
16
+ acts_as_table_value_provider
17
+
18
+ # Returns the ActsAsTable column model for this ActsAsTable primary key or `nil`.
19
+ #
20
+ # @return [ActsAsTable::ColumnModel, nil]
21
+ belongs_to :column_model, **{
22
+ class_name: 'ActsAsTable::ColumnModel',
23
+ inverse_of: :primary_keys,
24
+ required: false,
25
+ }
26
+
27
+ # Returns the ActsAsTable record model for this ActsAsTable primary key.
28
+ belongs_to :record_model, **{
29
+ class_name: 'ActsAsTable::RecordModel',
30
+ inverse_of: :primary_keys,
31
+ required: true,
32
+ }
33
+
34
+ # Returns the ActsAsTable values that have been provided by this ActsAsTable primary key.
35
+ has_many :values, **{
36
+ as: :value_provider,
37
+ class_name: 'ActsAsTable::Value',
38
+ dependent: :restrict_with_exception,
39
+ foreign_key: 'value_provider_id',
40
+ foreign_type: 'value_provider_type',
41
+ inverse_of: :value_provider,
42
+ }
43
+
44
+ validates :method_name, **{
45
+ presence: true,
46
+ }
47
+
48
+ validates :record_model_id, **{
49
+ uniqueness: true,
50
+ }
51
+
52
+ validate :record_model_class_must_respond_to_method_name, **{
53
+ if: ::Proc.new { |primary_key| primary_key.method_name.present? },
54
+ }
55
+
56
+ protected
57
+
58
+ # @param [ActiveRecord::Base, nil] base
59
+ # @return [Object, nil]
60
+ def _get_value(base = nil)
61
+ if base.nil?
62
+ nil
63
+ else
64
+ base.send(:"#{self.method_name}")
65
+ end
66
+ end
67
+
68
+ # @param [ActiveRecord::Base, nil] base
69
+ # @param [Object, nil] new_value
70
+ # @return [Array<Object>]
71
+ def _set_value(base = nil, new_value = nil)
72
+ if base.nil?
73
+ [
74
+ nil,
75
+ false,
76
+ ]
77
+ else
78
+ # @return [Object, nil]
79
+ orig_value = _get_value(base)
80
+
81
+ [
82
+ orig_value,
83
+ false,
84
+ ]
85
+ end
86
+ end
87
+
88
+ private
89
+
90
+ # @param [Class] klass
91
+ # @param [String] column_name
92
+ # @return [Boolean]
93
+ def _column?(klass, column_name)
94
+ klass.column_names.include?(column_name.to_s)
95
+ end
96
+
97
+ # @return [void]
98
+ def record_model_class_must_respond_to_method_name
99
+ self.record_model.try { |record_model| record_model.class_name.constantize rescue nil }.try { |klass|
100
+ unless _column?(klass, self.method_name)
101
+ self.errors.add('method_name', :required)
102
+ end
103
+ }
104
+
105
+ return
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,109 @@
1
+ module ActsAsTable
2
+ # ActsAsTable record.
3
+ #
4
+ # @!attribute [rw] position
5
+ # Returns the position of this ActsAsTable record.
6
+ #
7
+ # @return [Integer]
8
+ # @!attribute [r] record_errors_count
9
+ # Returns the number of ActsAsTable record errors for this ActsAsTable record.
10
+ #
11
+ # @return [Integer]
12
+ # @!attribute [rw] record_model_changed
13
+ # Returns `true` if the ActsAsTable record model changed the record for this ActsAsTable record. Otherwise, returns `false`.
14
+ #
15
+ # @return [Boolean]
16
+ # @!attribute [r] values_count
17
+ # Returns the number of ActsAsTable values for this ActsAsTable record.
18
+ #
19
+ # @return [Integer]
20
+ class Record < ::ActiveRecord::Base
21
+ # @!parse
22
+ # include ActsAsTable::ValueProvider
23
+ # include ActsAsTable::ValueProviderAssociationMethods
24
+
25
+ self.table_name = ActsAsTable.records_table
26
+
27
+ # Returns the record for this ActsAsTable record or `nil`.
28
+ #
29
+ # @return [ActiveRecord::Base, nil]
30
+ belongs_to :base, **{
31
+ polymorphic: true,
32
+ required: false,
33
+ }
34
+
35
+ # Returns the ActsAsTable record model for this ActsAsTable record.
36
+ belongs_to :record_model, **{
37
+ class_name: 'ActsAsTable::RecordModel',
38
+ inverse_of: :records,
39
+ required: true,
40
+ }
41
+
42
+ # Returns the ActsAsTable table for this ActsAsTable record.
43
+ belongs_to :table, **{
44
+ class_name: 'ActsAsTable::Table',
45
+ counter_cache: 'records_count',
46
+ inverse_of: :records,
47
+ required: true,
48
+ }
49
+
50
+ # Returns the ActsAsTable record errors for this ActsAsTable record.
51
+ has_many :record_errors, -> { order(attribute_name: :asc, message: :asc) }, **{
52
+ autosave: true,
53
+ class_name: 'ActsAsTable::RecordError',
54
+ dependent: :destroy,
55
+ foreign_key: 'record_id',
56
+ inverse_of: :record,
57
+ validate: true,
58
+ }
59
+
60
+ # Returns the ActsAsTable values for this ActsAsTable record.
61
+ has_many :values, -> { order(position: :asc) }, **{
62
+ autosave: true,
63
+ class_name: 'ActsAsTable::Value',
64
+ dependent: :destroy,
65
+ foreign_key: 'record_id',
66
+ inverse_of: :record,
67
+ validate: true,
68
+ }
69
+
70
+ validates :position, **{
71
+ numericality: {
72
+ greater_than_or_equal_to: 1,
73
+ only_integer: true,
74
+ },
75
+ presence: true,
76
+ uniqueness: {
77
+ scope: ['table_id', 'record_model_id'],
78
+ },
79
+ }
80
+
81
+ # validates :record_model_changed, **{}
82
+
83
+ validate :record_must_be_valid_class, :record_model_must_belong_to_row_model_for_table, **{
84
+ if: ::Proc.new { |record| record.record_model.present? },
85
+ }
86
+
87
+ private
88
+
89
+ # @return [void]
90
+ def record_must_be_valid_class
91
+ self.record_type.try { |record_type|
92
+ unless record_type.eql?(self.record_model.class_name)
93
+ self.errors.add('record_type', :invalid)
94
+ end
95
+ }
96
+ end
97
+
98
+ # @return [void]
99
+ def record_model_must_belong_to_row_model_for_table
100
+ self.table.try(:row_model).try(:record_models).try { |record_models|
101
+ unless record_models.include?(self.record_model)
102
+ self.errors.add('record_model_id', :invalid)
103
+ end
104
+ }
105
+
106
+ return
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,50 @@
1
+ module ActsAsTable
2
+ # ActsAsTable record error.
3
+ #
4
+ # @!attribute [rw] attribute_name
5
+ # Returns the attribute name for this ActsAsTable record error.
6
+ #
7
+ # @note The attribute name for model-level errors is "base".
8
+ #
9
+ # @return [String]
10
+ # @!attribute [rw] message
11
+ # Returns the message for this ActsAsTable record error.
12
+ #
13
+ # @return [String]
14
+ class RecordError < ::ActiveRecord::Base
15
+ # @!parse
16
+ # include ActsAsTable::ValueProvider
17
+ # include ActsAsTable::ValueProviderAssociationMethods
18
+
19
+ self.table_name = ActsAsTable.record_errors_table
20
+
21
+ # Returns the ActsAsTable record for this error.
22
+ belongs_to :record, **{
23
+ class_name: 'ActsAsTable::Record',
24
+ counter_cache: 'record_errors_count',
25
+ inverse_of: :record_errors,
26
+ required: true,
27
+ }
28
+
29
+ # Returns the ActsAsTable value for this error or `nil`.
30
+ #
31
+ # @return [ActsAsTable::Value, nil]
32
+ belongs_to :value, **{
33
+ class_name: 'ActsAsTable::Value',
34
+ counter_cache: 'record_errors_count',
35
+ inverse_of: :record_errors,
36
+ required: false,
37
+ }
38
+
39
+ validates :attribute_name, **{
40
+ presence: true,
41
+ }
42
+
43
+ validates :message, **{
44
+ presence: true,
45
+ uniqueness: {
46
+ scope: ['record_id', 'attribute_name'],
47
+ },
48
+ }
49
+ end
50
+ end
@@ -0,0 +1,194 @@
1
+ module ActsAsTable
2
+ # ActsAsTable record model (value provider).
3
+ #
4
+ # @!attribute [rw] class_name
5
+ # Returns the ActiveRecord model class name for this ActsAsTable record model.
6
+ #
7
+ # @return [String]
8
+ class RecordModel < ::ActiveRecord::Base
9
+ # @!parse
10
+ # include ActsAsTable::ValueProvider
11
+ # include ActsAsTable::ValueProvider::InstanceMethods
12
+ # include ActsAsTable::ValueProviderAssociationMethods
13
+
14
+ self.table_name = ActsAsTable.record_models_table
15
+
16
+ acts_as_table_value_provider
17
+
18
+ # Returns the ActsAsTable row model for this ActsAsTable record model.
19
+ belongs_to :row_model, **{
20
+ class_name: 'ActsAsTable::RowModel',
21
+ inverse_of: :record_models,
22
+ required: true,
23
+ }
24
+
25
+ # Returns the ActsAsTable singular macro associations where this ActsAsTable record model is the source of the association.
26
+ has_many :belongs_tos_as_source, **{
27
+ autosave: true,
28
+ class_name: 'ActsAsTable::BelongsTo',
29
+ dependent: :destroy,
30
+ foreign_key: 'source_record_model_id',
31
+ inverse_of: :source_record_model,
32
+ validate: true,
33
+ }
34
+
35
+ # Returns the ActsAsTable singular macro associations where this ActsAsTable record model is the target of the association.
36
+ has_many :belongs_tos_as_target, **{
37
+ autosave: true,
38
+ class_name: 'ActsAsTable::BelongsTo',
39
+ dependent: :destroy,
40
+ foreign_key: 'target_record_model_id',
41
+ inverse_of: :target_record_model,
42
+ validate: true,
43
+ }
44
+
45
+ # Returns the ActsAsTable foreign keys for this ActsAsTable record model.
46
+ has_many :foreign_keys, **{
47
+ autosave: true,
48
+ class_name: 'ActsAsTable::ForeignKey',
49
+ dependent: :destroy,
50
+ foreign_key: 'record_model_id',
51
+ inverse_of: :record_model,
52
+ validate: true,
53
+ }
54
+
55
+ # Returns the ActsAsTable collection macro associations where this ActsAsTable record model is the source of the association.
56
+ has_many :has_manies_as_source, **{
57
+ autosave: true,
58
+ class_name: 'ActsAsTable::HasMany',
59
+ dependent: :destroy,
60
+ foreign_key: 'source_record_model_id',
61
+ inverse_of: :source_record_model,
62
+ validate: true,
63
+ }
64
+
65
+ # Returns the ActsAsTable collection macro associations where this ActsAsTable record model is the target of the association.
66
+ has_many :has_manies_as_target, -> { readonly }, **{
67
+ source: :has_many,
68
+ through: :has_many_targets,
69
+ }
70
+
71
+ # Returns the ActsAsTable collection macro association targets for this ActsAsTable record model.
72
+ has_many :has_many_targets, **{
73
+ autosave: true,
74
+ class_name: 'ActsAsTable::HasManyTarget',
75
+ dependent: :destroy,
76
+ foreign_key: 'record_model_id',
77
+ inverse_of: :record_model,
78
+ validate: true,
79
+ }
80
+
81
+ # Returns the ActsAsTable attribute accessors for this ActsAsTable record model.
82
+ has_many :lenses, **{
83
+ autosave: true,
84
+ class_name: 'ActsAsTable::Lense',
85
+ dependent: :destroy,
86
+ foreign_key: 'record_model_id',
87
+ inverse_of: :record_model,
88
+ validate: true,
89
+ }
90
+
91
+ # Returns the ActsAsTable primary keys for this ActsAsTable record model.
92
+ has_many :primary_keys, **{
93
+ autosave: true,
94
+ class_name: 'ActsAsTable::PrimaryKey',
95
+ dependent: :destroy,
96
+ foreign_key: 'record_model_id',
97
+ inverse_of: :record_model,
98
+ validate: true,
99
+ }
100
+
101
+ # Returns the ActsAsTable records that have been provided by this ActsAsTable record model.
102
+ has_many :records, **{
103
+ class_name: 'ActsAsTable::Record',
104
+ dependent: :restrict_with_exception,
105
+ foreign_key: 'record_model_id',
106
+ inverse_of: :record_model,
107
+ }
108
+
109
+ # Returns the ActsAsTable row models where this ActsAsTable record model is the root.
110
+ has_many :row_models_as_root, **{
111
+ class_name: 'ActsAsTable::RowModel',
112
+ dependent: :restrict_with_exception,
113
+ foreign_key: 'root_record_model_id',
114
+ inverse_of: :root_record_model,
115
+ }
116
+
117
+ validates :class_name, **{
118
+ presence: true,
119
+ }
120
+
121
+ validate :base_must_be_reachable
122
+
123
+ validate :class_name_must_constantize, **{
124
+ if: ::Proc.new { |record_model| record_model.class_name.present? },
125
+ }
126
+
127
+ # Get the value for the given record using the given options.
128
+ #
129
+ # @param [ActiveRecord::Base, nil] base
130
+ # @param [Hash<Symbol, Object>] options
131
+ # @option options [Boolean] :default
132
+ # @return [ActsAsTable::ValueProvider::WrappedValue]
133
+ def get_value(base = nil, **options)
134
+ unless base.nil? || self.class_name.eql?(base.class.name)
135
+ raise ::ArgumentError.new("record - invalid class - expected: #{self.class_name.inspect}, found: #{base.inspect}")
136
+ end
137
+
138
+ # @return [Hash<ActsAsTable::ValueProvider::InstanceMethods, Object>]
139
+ value_by_value_provider = self.each_acts_as_table_value_provider(except: [:row_model]).inject({}) { |acc, value_provider|
140
+ acc[value_provider] ||= base.nil? ? ActsAsTable.adapter.wrap_value_for(value_provider, base, nil, nil) : ActsAsTable.adapter.get_value_for(value_provider, base, **options)
141
+ acc
142
+ }
143
+
144
+ ActsAsTable.adapter.wrap_value_for(self, base, nil, value_by_value_provider)
145
+ end
146
+
147
+ # Set the new value for the given record using the given options.
148
+ #
149
+ # @param [ActiveRecord::Base, nil] base
150
+ # @param [Hash<ActsAsTable::ValueProvider::InstanceMethods, Object>] new_value_by_value_provider
151
+ # @param [Hash<Symbol, Object>] options
152
+ # @option options [Boolean] :default
153
+ # @return [ActsAsTable::ValueProvider::WrappedValue]
154
+ def set_value(base = nil, new_value_by_value_provider = {}, **options)
155
+ unless base.nil? || self.class_name.eql?(base.class.name)
156
+ raise ::ArgumentError.new("record - invalid class - expected: #{self.class_name.inspect}, found: #{base.inspect}")
157
+ end
158
+
159
+ # @return [Array<Object>]
160
+ value_by_value_provider, changed = *self.each_acts_as_table_value_provider(except: [:row_model]).inject([{}, false]) { |acc, value_provider|
161
+ # @return [Object, nil]
162
+ new_value = new_value_by_value_provider.try(:[], value_provider)
163
+
164
+ acc[0][value_provider] ||= base.nil? ? ActsAsTable.adapter.wrap_value_for(value_provider, base, nil, nil) : ActsAsTable.adapter.set_value_for(value_provider, base, new_value, **options)
165
+ acc[1] ||= acc[0][value_provider].changed?
166
+ acc
167
+ }
168
+
169
+ ActsAsTable.adapter.wrap_value_for(self, base, nil, value_by_value_provider, changed: changed)
170
+ end
171
+
172
+ private
173
+
174
+ # @return [void]
175
+ def base_must_be_reachable
176
+ if self.row_model.try(:reachable_record_model?, self) == false
177
+ self.errors.add(:base, :unreachable)
178
+ end
179
+
180
+ return
181
+ end
182
+
183
+ # @return [void]
184
+ def class_name_must_constantize
185
+ begin
186
+ self.class_name.constantize
187
+ rescue ::NameError
188
+ self.errors.add('class_name', :invalid)
189
+ end
190
+
191
+ return
192
+ end
193
+ end
194
+ end