Class: AttrJson::Type::Model
- Inherits:
-
ActiveModel::Type::Value
- Object
- ActiveModel::Type::Value
- AttrJson::Type::Model
- Defined in:
- lib/attr_json/type/model.rb
Overview
An ActiveModel::Type representing a particular AttrJson::Model class, supporting casting, serialization, and deserialization from/to JSON-able serializable hashes.
You create one with AttrJson::Model::Type.new(attr_json_model_class), but normally that's only done in AttrJson::Model.to_type, there isn't an anticipated need to create from any other place.
Defined Under Namespace
Classes: BadCast
Instance Attribute Summary collapse
-
#model ⇒ Object
Returns the value of attribute model.
-
#strip_nils ⇒ Object
Returns the value of attribute strip_nils.
Instance Method Summary collapse
- #cast(v) ⇒ Object
-
#changed_in_place?(raw_old_value, new_value) ⇒ Boolean
these guys are definitely mutable, so we need this.
- #deserialize(v) ⇒ Object
-
#initialize(model, strip_nils: :safely) ⇒ Model
constructor
A new instance of Model.
- #serialize(v) ⇒ Object
- #type ⇒ Object
-
#value_for_contains_query(key_path_arr, value) ⇒ Object
This is used only by our own keypath-chaining query stuff.
Constructor Details
#initialize(model, strip_nils: :safely) ⇒ Model
Returns a new instance of Model.
25 26 27 28 29 |
# File 'lib/attr_json/type/model.rb', line 25 def initialize(model, strip_nils: :safely) #TODO type check, it really better be a AttrJson::Model. maybe? @model = model @strip_nils = strip_nils end |
Instance Attribute Details
#model ⇒ Object
Returns the value of attribute model.
17 18 19 |
# File 'lib/attr_json/type/model.rb', line 17 def model @model end |
#strip_nils ⇒ Object
Returns the value of attribute strip_nils.
17 18 19 |
# File 'lib/attr_json/type/model.rb', line 17 def strip_nils @strip_nils end |
Instance Method Details
#cast(v) ⇒ Object
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 |
# File 'lib/attr_json/type/model.rb', line 35 def cast(v) if v.nil? # important to stay nil instead of empty object, because they # are different things. v elsif v.kind_of? model v elsif v.respond_to?(:to_hash) # to_hash is actually the 'implicit' conversion, it really is a hash # even though it isn't is_a?(Hash), try to_hash first before to_h, # the explicit conversion. model.new(v.to_hash) elsif v.respond_to?(:to_h) # TODO Maybe we ought not to do this on #to_h? model.new(v.to_h) elsif model.attr_json_config.bad_cast == :as_nil # This was originally default behavior, to be like existing ActiveRecord # which kind of silently does this for non-castable basic values. That # ended up being confusing in the basic case, so now we raise by default, # but this is still configurable. nil else raise BadCast.new("Can not cast from #{v.inspect} to #{self.type}") end end |
#changed_in_place?(raw_old_value, new_value) ⇒ Boolean
these guys are definitely mutable, so we need this.
100 101 102 |
# File 'lib/attr_json/type/model.rb', line 100 def changed_in_place?(raw_old_value, new_value) serialize(new_value) != raw_old_value end |
#deserialize(v) ⇒ Object
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 |
# File 'lib/attr_json/type/model.rb', line 71 def deserialize(v) if v.nil? # important to stay nil instead of empty object, because they # are different things. v elsif v.kind_of? model v elsif v.respond_to?(:to_hash) # to_hash is actually the 'implicit' conversion, it really is a hash # even though it isn't is_a?(Hash), try to_hash first before to_h, # the explicit conversion. model.new_from_serializable(v.to_hash) elsif v.respond_to?(:to_h) # TODO Maybe we ought not to do this on #to_h? especially here in deserialize? model.new_from_serializable(v.to_h) elsif model.attr_json_config.bad_cast == :as_nil # TODO should we have different config value for bad_deserialize vs bad_cast? # This was originally default behavior, to be like existing ActiveRecord # which kind of silently does this for non-castable basic values. That # ended up being confusing in the basic case, so now we raise by default, # but this is still configurable. nil else raise BadCast.new("Can not cast from #{v.inspect} to #{self.type}") end end |
#serialize(v) ⇒ Object
61 62 63 64 65 66 67 68 69 |
# File 'lib/attr_json/type/model.rb', line 61 def serialize(v) if v.nil? nil elsif v.kind_of?(model) v.serializable_hash(strip_nils: strip_nils) else (cast_v = cast(v)) && cast_v.serializable_hash(strip_nils: strip_nils) end end |
#type ⇒ Object
31 32 33 |
# File 'lib/attr_json/type/model.rb', line 31 def type model.to_param.underscore.to_sym end |
#value_for_contains_query(key_path_arr, value) ⇒ Object
This is used only by our own keypath-chaining query stuff.
105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/attr_json/type/model.rb', line 105 def value_for_contains_query(key_path_arr, value) first_key, rest_keys = key_path_arr.first, key_path_arr[1..-1] attr_def = model.attr_json_registry.fetch(first_key) { attr_def.store_key => if rest_keys.present? attr_def.type.value_for_contains_query(rest_keys, value) else attr_def.serialize(attr_def.cast value) end } end |