Module: ActiveModelSerializerPlus::Assignment
- Defined in:
- lib/active_model_serializer_plus/assignment.rb
Overview
Default implementation of the #attributes= method for ActiveModel classes.
This is the base of the JSON and Xml modules. It supplies a standard #attributes= method to classes that follows the basic pattern of the custom one you’d normally write and adds the ability to pick up object type information from the #attributes_types hash to convert the hash values of contained objects into actual objects. This mostly eliminates the need to write custom #attributes= methods for each class with code to check attribute names and initialize objects from child hashes.
The standard ActiveModel/ActiveRecord serialization/deserialization has some flaws, for instance it will serialize classes as contained hashes whether or not they have an #attributes= method available to deserialize them. We work around that by having building Procs which can do the correct thing in many cases.
Instance Method Summary collapse
-
#attributes=(hash) ⇒ self
The default
#attributes=method which assigns a hash to the object’s attributes.
Instance Method Details
#attributes=(hash) ⇒ self
The default #attributes= method which assigns a hash to the object’s attributes.
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 |
# File 'lib/active_model_serializer_plus/assignment.rb', line 25 def attributes=(hash) hash.each do |key, value| # Check #attribute_types for what type this item should be, and if we have an entry # convert it to an actual Class object we can use. klass = nil v = nil v = self.attribute_types[key] if self.respond_to?(:attribute_types) && self.attribute_types.is_a?(Hash) begin klass = ActiveModelSerializerPlus.to_class(v) unless v.nil? rescue ArgumentError raise ArgumentError, "Type #{v.to_s} for attribute #{key.to_s} is not a valid type." end unless klass.nil? if value.is_a?(Hash) # If we're looking at a contained object (our value is a hash), see if we have a Proc # to build the object from a hash. If we don't, fall back to creating an object and # using the hash #attributes= method if possible. If all else fails just leave the value v = ActiveModelSerializerPlus.build(klass.name, value) if v.nil? && klass.method_defined?('attributes=') v = klass.new v.attributes = value end value = v unless v.nil? elsif value.is_a?(String) v = ActiveModelSerializerPlus.parse(klass.name, value) value = v if v end end self.send("#{key}=", value) end self end |