app/models/bento_search/results/serialization.rb in bento_search-1.5.0 vs app/models/bento_search/results/serialization.rb in bento_search-1.6.0

- old
+ new

@@ -2,25 +2,25 @@ require 'active_support/concern' require 'json' require 'date' # Call #dump_to_json on a BentoSearch value object (such as BentoSearch::Result or ::Author) -# to get it in Json +# to get it in Json # # Values marked with serializable_attr in BentoSearch::Result are -# included in seralization. +# included in seralization. # # At present metadata and configuration are NOT serialized: #decorator, #display_configuration, # and #engine_id are not included in the serialization, so when loaded from serialization, -# ResultItems will not have such things set. -# +# ResultItems will not have such things set. +# # * Works by getting and setting instance variables directly, ignores getters/setters # # * This means decorated values are NOT included in serialization, the raw # values are what is serialized. This is intended, we serialize internal # state, not decoration which can be recreated. You should make sure the decorators you -# want are applied after de-serialization. +# want are applied after de-serialization. # # * preserves html_safety status in serialization, by adding extra `_attr_htmlsafe: true` key/value # module BentoSearch::Results::Serialization extend ActiveSupport::Concern @@ -29,26 +29,27 @@ class_attribute :_serializable_attrs, :_serializable_attr_options self._serializable_attrs = [] self._serializable_attr_options = {} end + class_methods do # Just a macro to mark a property name serializable -- the name is # of an instance method that will be included in our serializations - # and de-serializations. + # and de-serializations. # # Options: # * collection_of: String fully qualified name of a class that is # is also BentoSearch::Results::Serialization, the attribute - # is an array of these. + # is an array of these. # * serializer: String fully qualified class name of a serializer # class that has a `dump` and a `load` for individual values, # we just use it for Date now, see BentoSearch::Results::Serialization::Date def serializable_attr(symbol, options = nil) symbol = symbol.to_s self._serializable_attrs << symbol - if options + if options self._serializable_attr_options[symbol] = options end end # convenience macro to do attr_accessor AND mark it @@ -65,18 +66,18 @@ next if key =~ /\A_.*_htmlsafe\Z/ if _serializable_attr_options[key] && _serializable_attr_options[key][:collection_of] - klass = qualified_const_get(_serializable_attr_options[key][:collection_of]) + klass = correct_const_get(_serializable_attr_options[key][:collection_of]) value = value.collect do |item| klass.from_internal_state_hash(item) end end if _serializable_attr_options[key] && _serializable_attr_options[key][:serializer] - klass = qualified_const_get(_serializable_attr_options[key][:serializer]) + klass = correct_const_get(_serializable_attr_options[key][:serializer]) value = klass.load(value) end if hash["_#{key}_htmlsafe"] == true && value.respond_to?(:html_safe) value = value.html_safe @@ -90,22 +91,30 @@ def load_json(json_str) self.from_internal_state_hash( JSON.parse! json_str ) end + def correct_const_get(str) + if Gem::Version.new(Rails.version) > Gem::Version.new('4.2.99') + const_get(str) + else + qualified_const_get(str) + end + end + end def internal_state_hash hash = {} self._serializable_attrs.each do |accessor| accessor = accessor.to_s - value = self.instance_variable_get("@#{accessor}") + value = self.instance_variable_defined?("@#{accessor}") && self.instance_variable_get("@#{accessor}") next if value.blank? if _serializable_attr_options[accessor] && _serializable_attr_options[accessor][:serializer] - klass = self.class.qualified_const_get(_serializable_attr_options[accessor][:serializer]) + klass = self.class.correct_const_get(_serializable_attr_options[accessor][:serializer]) value = klass.dump(value) elsif value.respond_to?(:to_ary) value = value.to_ary.collect do |item| item.respond_to?(:internal_state_hash) ? item.internal_state_hash : item end @@ -131,6 +140,6 @@ def self.load(str) ::Date.iso8601(str) end end -end \ No newline at end of file +end