Module: ActiveJsonModel::Array
- Defined in:
- lib/active_json_model/array.rb
Defined Under Namespace
Modules: ClassMethods
Class Method Summary collapse
Instance Method Summary collapse
-
#active_json_model_validate ⇒ Object
Validate method that handles recursive validation into models in the array.
- #dump_to_json ⇒ Object
-
#dumped? ⇒ Boolean
Was this instance dumped to JSON?.
-
#load_from_json(json_array) ⇒ Object
Load array for this instance from a JSON array.
-
#loaded? ⇒ Boolean
Was this instance loaded from JSON?.
-
#new? ⇒ Boolean
Is this a new instance that was created without loading, and has yet to be dumped?.
-
#values_set? ⇒ Boolean
Have the values for this array actually be set, or a defaults coming through?.
Class Method Details
.included(base_class) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/active_json_model/array.rb', line 16 def self.included(base_class) # Add all the class methods to the included class base_class.extend(ClassMethods) # Add additional settings into the class base_class.class_eval do # Make sure the objects will be ActiveModels include ::ActiveModel::Model unless include?(::ActiveModel::Model) # This class will be have like a list-like object include ::Enumerable unless include?(::Enumerable) # Make sure that it has dirty tracking include ::ActiveModel::Dirty unless include?(::ActiveModel::Dirty) # The raw values for the attr_accessor :values # Most of the functionality gets delegated to the actual values array. This is almost all possible methods for # array, leaving off those that might be problems for equality checking, etc. delegate :try_convert, :&, :*, :+, :-, :<<, :<=>, :[], :[]=, :all?, :any?, :append, :assoc, :at, :bsearch, :bsearch_index, :clear, :collect, :collect!, :combination, :compact, :compact!, :concat, :count, :cycle, :deconstruct, :delete, :delete_at, :delete_if, :difference, :dig, :drop, :drop_while, :each, :each_index, :empty?, :eql?, :fetch, :fill, :filter!, :find_index, :first, :flatten, :flatten!, :hash, :include?, :index, :initialize_copy, :insert, :inspect, :intersection, :join, :keep_if, :last, :length, :map, :map!, :max, :min, :minmax, :none?, :old_to_s, :one?, :pack, :permutation, :pop, :prepend, :product, :push, :rassoc, :reject, :reject!, :repeated_combination, :repeated_permutation, :replace, :reverse, :reverse!, :reverse_each, :rindex, :rotate, :rotate!, :sample, :select!, :shift, :shuffle, :shuffle!, :size, :slice, :slice!, :sort, :sort!, :sort_by!, :sum, :take, :take_while, :transpose, :union, :uniq, :uniq!, :unshift, :values_at, :zip, :|, to: :values # Has this model changed? Override's <code>ActiveModel::Dirty</code>'s base behavior to properly handle # recursive changes. # # @return [Boolean] true if any attribute has changed, false otherwise def changed? # Note: this method is implemented here versus in the module overall because if it is implemented in the # module overall, it doesn't properly override the implementation for <code>ActiveModel::Dirty</code> that # gets dynamically pulled in using the <code>included</code> hook. super || values != @_active_json_model_original_values || values&.any?{|val| val&.respond_to?(:changed?) && val.changed? } end # For new/loaded tracking @_active_json_model_dumped = false @_active_json_model_loaded = false # Register model validation to handle recursive validation into the model tree validate :active_json_model_validate def initialize(arr=nil, **kwargs) if !arr.nil? && !kwargs[:values].nil? raise ArgumentError.new('Can only specify either array or values for ActiveJsonModel::Array') end # Just repackage as named parameters kwargs[:values] = arr unless arr.nil? unless kwargs.key?(:values) kwargs[:values] = [] end # Invoke the superclass constructor to let active model do the work of setting the attributes super(**kwargs).tap do |_| # Clear out any recorded changes as this object is starting fresh clear_changes_information @_active_json_model_original_values = self.values end end # Select certain values based on a condition and generate a new ActiveJsonModel Array # @return [ActiveJsonModel] the filtered array def select(&block) if block self.class.new(values: values.select(&block)) else values.select end end # As in the real implementation, <code>filter</code> is just <code>select</code> alias_method :filter, :select end end |
Instance Method Details
#active_json_model_validate ⇒ Object
Validate method that handles recursive validation into models in the array. Individual validations on attributes for this model will be handled by the standard mechanism.
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/active_json_model/array.rb', line 195 def active_json_model_validate errors.add(:values, 'ActiveJsonModel::Array values must be an array') unless values.is_a?(::Array) values.each_with_index do |val, i| # Check if attribute value is an ActiveJsonModel if val && val.respond_to?(:valid?) # This call to <code>valid?</code> is important because it will actually trigger recursive validations unless val.valid? val.errors.each do |error| errors.add("[#{i}].#{error.attribute}".to_sym, error.) end end end if self.class.active_json_model_array_serialization_tuple.validate_proc # It's a proc (likely lambda) if self.class.active_json_model_array_serialization_tuple.validate_proc.arity == 4 # Handle the validator_for_item_type validators that need to take the self as a param # for recursive validators self.class.active_json_model_array_serialization_tuple.validate_proc.call(val, i, errors, self) else self.class.active_json_model_array_serialization_tuple.validate_proc.call(val, i, errors) end elsif self.class.active_json_model_array_serialization_tuple.validate_method # It's implemented as method on this object send(self.class.active_json_model_array_serialization_tuple.validate_method, val, i) end end end |
#dump_to_json ⇒ Object
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/active_json_model/array.rb', line 170 def dump_to_json # Record that the data has been dumped @_active_json_model_dumped = true unless self.class.active_json_model_array_serialization_tuple raise RuntimeError.new('ActiveJsonModel::Array not properly configured') end return nil if values.nil? values.map do |val| if self.class.active_json_model_array_serialization_tuple.serialize_proc self.class.active_json_model_array_serialization_tuple.serialize_proc.call(val) else send(self.class.active_json_model_array_serialization_tuple.deserialize_method, val) end end.tap do |vals| # All changes are cleared after dump clear_changes_information @_active_json_model_original_values = vals end end |
#dumped? ⇒ Boolean
Was this instance dumped to JSON?
109 110 111 |
# File 'lib/active_json_model/array.rb', line 109 def dumped? @_active_json_model_dumped end |
#load_from_json(json_array) ⇒ Object
Load array for this instance from a JSON array
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/active_json_model/array.rb', line 128 def load_from_json(json_array) # Record this object was loaded @_active_json_model_loaded = true if json_array.nil? if self.class.active_json_model_array_serialization_tuple.nil_data_to_empty_array self.values = [] else self.values = nil end @_active_json_model_values_set = false return end if !json_array.respond_to?(:map) || json_array.is_a?(Hash) raise ArgumentError.new("Invalid value specified for json_array. Expected array-like object received #{json_array.class}") end # Record that we have some sort of values set @_active_json_model_values_set = true # Iterate over all the allowed attributes self.values = json_array.map do |json_val| if self.class.active_json_model_array_serialization_tuple.deserialize_proc self.class.active_json_model_array_serialization_tuple.deserialize_proc.call(json_val) else send(self.class.active_json_model_array_serialization_tuple.deserialize_method, json_val) end end # Now that the load is complete, mark dirty tracking as clean clear_changes_information @_active_json_model_original_values = self.values # Invoke any on-load callbacks self.class.ancestry_active_json_model_load_callbacks.each do |cb| cb.invoke(self) end end |
#loaded? ⇒ Boolean
Was this instance loaded from JSON?
103 104 105 |
# File 'lib/active_json_model/array.rb', line 103 def loaded? @_active_json_model_loaded end |
#new? ⇒ Boolean
Is this a new instance that was created without loading, and has yet to be dumped?
115 116 117 |
# File 'lib/active_json_model/array.rb', line 115 def new? !loaded? && !dumped? end |
#values_set? ⇒ Boolean
Have the values for this array actually be set, or a defaults coming through?
121 122 123 |
# File 'lib/active_json_model/array.rb', line 121 def values_set? !!@_active_json_model_values_set end |