Class: SuperAwesomeResourceSerializer
- Inherits:
-
Object
- Object
- SuperAwesomeResourceSerializer
- Defined in:
- lib/super_awesome_resource_serializer.rb
Overview
This class provides the base functionality for serializing Activeobject objects to XML, JSON, or YAML. It is intended to be used with web services where tighter control is desired than is provided by ActiveResource out of the box. For instance, you may have some sensitive fields in your Activeobject that should not be made available through a public web service API unless the user is a trusted user.
To create a serializer for you model, you simply need to make a new class named ModelNameSerializer where ModelName is the class name of your model. The serializer class itself then needs to define how each field should be serialized using the serialize method.
Defined Under Namespace
Classes: SerializedFieldInfo
Constant Summary collapse
- STATIC_CLASSES =
[String, Symbol, Fixnum, Float, NilClass, TrueClass, FalseClass, Object].inject({}){|hash, klass| hash[klass] = true; hash}
Instance Attribute Summary collapse
-
#exclude_fields ⇒ Object
readonly
Returns the value of attribute exclude_fields.
-
#include_fields ⇒ Object
readonly
Returns the value of attribute include_fields.
-
#object ⇒ Object
readonly
Returns the value of attribute object.
-
#only_fields ⇒ Object
readonly
Returns the value of attribute only_fields.
-
#root_element ⇒ Object
readonly
Returns the value of attribute root_element.
Class Method Summary collapse
-
.for_object(object, options = {}, klass = object.class) ⇒ Object
Get the serializer class for a given object.
-
.merge_field_lists(list_1, list_2) ⇒ Object
Merge the values of two field lists as used in :include, :exclude, and :only options.
-
.normalize_field_list(field_list) ⇒ Object
Turn an :include, :exclude, or :only field list into a hash for consistent access.
-
.param_key ⇒ Object
Get the field name with the unique key used to lookup the object.
-
.param_key=(val) ⇒ Object
Set the field name with the unique key used to lookup the object.
-
.serializable_fields(action, options = {}) ⇒ Object
Get a list of serialized field information for preforming an action (either :getter or :setter) on the class.
-
.serialize(field, options = {}) ⇒ Object
Define how to serialize and deserialize a field.
Instance Method Summary collapse
- #==(val) ⇒ Object
-
#initialize(object, serialize_options = {}) ⇒ SuperAwesomeResourceSerializer
constructor
Create a new serializer.
-
#set_attributes(attributes) ⇒ Object
Set the attributes on the underlying object by calling the available setters.
-
#to_hash ⇒ Object
Serialize the object to a hash.
-
#to_json(json_options = nil) ⇒ Object
Serialize the object to JSON.
-
#to_param ⇒ Object
Get the unique key used for lookups.
-
#to_xml(xml_options = {}) ⇒ Object
Serialize the object to XML.
-
#to_yaml(yaml_options = {}) ⇒ Object
Serialize the object to YAML.
-
#update_with_json(json) ⇒ Object
Update the available fields in the object with a serialized representation of the object in JSON.
-
#update_with_xml(xml) ⇒ Object
Update the available fields in the object with a serialized representation of the object in XML.
-
#update_with_yaml(yaml) ⇒ Object
Update the available fields in the object with a serialized representation of the object in YAML.
Constructor Details
#initialize(object, serialize_options = {}) ⇒ SuperAwesomeResourceSerializer
Create a new serializer. Options can be passed in for :exclude, :include, or :only to determine which fields will be used.
To indicate a field should be included or excluded on a serializer returned by a field, prefix it with the field name. For example, if you have a field :venue and this field returns a VenueSerializer object and you only want the id of the venue, you can specify :only => “venue.id”.
161 162 163 164 165 166 167 |
# File 'lib/super_awesome_resource_serializer.rb', line 161 def initialize (object, = {}) @object = object @include_fields = self.class.normalize_field_list([:include]) @exclude_fields = self.class.normalize_field_list([:exclude]) @only_fields = self.class.normalize_field_list([:only]) @root_element = [:root_element] ? [:root_element].to_s : object.class.name.underscore.gsub("/", "-") end |
Instance Attribute Details
#exclude_fields ⇒ Object (readonly)
Returns the value of attribute exclude_fields.
153 154 155 |
# File 'lib/super_awesome_resource_serializer.rb', line 153 def exclude_fields @exclude_fields end |
#include_fields ⇒ Object (readonly)
Returns the value of attribute include_fields.
153 154 155 |
# File 'lib/super_awesome_resource_serializer.rb', line 153 def include_fields @include_fields end |
#object ⇒ Object (readonly)
Returns the value of attribute object.
153 154 155 |
# File 'lib/super_awesome_resource_serializer.rb', line 153 def object @object end |
#only_fields ⇒ Object (readonly)
Returns the value of attribute only_fields.
153 154 155 |
# File 'lib/super_awesome_resource_serializer.rb', line 153 def only_fields @only_fields end |
#root_element ⇒ Object (readonly)
Returns the value of attribute root_element.
153 154 155 |
# File 'lib/super_awesome_resource_serializer.rb', line 153 def root_element @root_element end |
Class Method Details
.for_object(object, options = {}, klass = object.class) ⇒ Object
Get the serializer class for a given object.
19 20 21 22 23 24 25 26 27 28 |
# File 'lib/super_awesome_resource_serializer.rb', line 19 def for_object (object, = {}, klass = object.class) serializer_class = "#{klass.name}Serializer".constantize return serializer_class.new(object, ) rescue if klass.superclass.nil? raise NameError.new("no known serializers for class #{object.class.name}") else return for_object(object, , klass.superclass) end end |
.merge_field_lists(list_1, list_2) ⇒ Object
Merge the values of two field lists as used in :include, :exclude, and :only options.
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/super_awesome_resource_serializer.rb', line 44 def merge_field_lists (list_1, list_2) if list_1.blank? if list_2.blank? return nil else return list_2 end elsif list_2.blank? return list_1 else list_1 = normalize_field_list(list_1) list_2 = normalize_field_list(list_2) merge_hashes(list_1, list_2) end end |
.normalize_field_list(field_list) ⇒ Object
Turn an :include, :exclude, or :only field list into a hash for consistent access.
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 |
# File 'lib/super_awesome_resource_serializer.rb', line 61 def normalize_field_list (field_list) case field_list when nil return {} when true return {} when String return {field_list.to_sym => true} when Symbol return {field_list => true} when Array hash = {} field_list.each do |value| if value.is_a?(Hash) hash.merge!(normalize_field_list(value)) else hash[value.to_sym] = true end end return hash when Hash hash = {} field_list.each_pair do |key, value| value = normalize_field_list(value) unless value == true hash[key.to_sym] = value end return hash else raise ArgumentError.new("illegal type in field list: #{field_list.class.name}") end end |
.param_key ⇒ Object
Get the field name with the unique key used to lookup the object
120 121 122 123 124 125 126 127 128 |
# File 'lib/super_awesome_resource_serializer.rb', line 120 def param_key if @param_key @param_key elsif superclass < SuperAwesomeResourceSerializer superclass.param_key else :id end end |
.param_key=(val) ⇒ Object
Set the field name with the unique key used to lookup the object
131 132 133 |
# File 'lib/super_awesome_resource_serializer.rb', line 131 def param_key= (val) @param_key = val end |
.serializable_fields(action, options = {}) ⇒ Object
Get a list of serialized field information for preforming an action (either :getter or :setter) on the class. Option can pass in values for :include, :exclude, and :only to indicate filters on what fields are allowed. Include can be used to add fields that have been defined but excluded by default, exclude can be used to remove fields included by default, while only is used to specify the exact list of fields to use.
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/super_awesome_resource_serializer.rb', line 97 def serializable_fields (action, = {}) if self == SuperAwesomeResourceSerializer return [] else exclude_fields = [:exclude] || {} include_fields = [:include] || {} only_fields = [:only] || {} all_field_info = superclass.serializable_fields() + serialized_field_info if only_fields.empty? excluded_field_names = exclude_fields.collect{|k,v| k if v == true}.compact excluded_field_names = (excluded_field_names + all_field_info.select{|field| field.excluded?(action)}.collect{|field| field.name}) - include_fields.keys all_field_info.delete_if{|field| excluded_field_names.include?(field.name)} unless excluded_field_names.empty? else all_field_info.delete_if{|field| not only_fields.include?(field.name)} end return all_field_info end end |
.serialize(field, options = {}) ⇒ Object
Define how to serialize and deserialize a field. The following options can be passed in to define how to serialize an object.
-
:element - The name of the field in the serialized output. This can be used to give a object a prettier name on output.
-
:getter - The getter to get the field value.
-
:setter - The setter to set the field value.
-
:exclude - Indicate that this field should be excluded unless specifically asked for. Values can be :getter, :setter, or true.
By default, getters and setters will call the field accessor on the serializer (if it is defined) or on the object. This can be overridden by specifying a different method name to call, or a proc that will be yielded to with the object (and value for a setter). Finally, getters and setters can be disabled by setting them to false.
39 40 41 |
# File 'lib/super_awesome_resource_serializer.rb', line 39 def serialize (field, = {}) serialized_field_info << SerializedFieldInfo.new(field, ) end |
Instance Method Details
#==(val) ⇒ Object
227 228 229 |
# File 'lib/super_awesome_resource_serializer.rb', line 227 def == (val) return val.is_a?(self.class) && val.object == object && val.include_fields == include_fields && val.exclude_fields == exclude_fields && val.only_fields == only_fields && val.root_element == root_element end |
#set_attributes(attributes) ⇒ Object
Set the attributes on the underlying object by calling the available setters. All keys in the hash (and in any hashes in the values) will be converted to symbols.
171 172 173 174 175 176 177 178 179 |
# File 'lib/super_awesome_resource_serializer.rb', line 171 def set_attributes (attributes) return unless attributes attributes = normalize_attribute_keys(attributes) serializable_fields(:setter).each do |field| if attributes.include?(field.name) field.set(self, attributes[field.name]) end end end |
#to_hash ⇒ Object
Serialize the object to a hash.
197 198 199 200 201 202 203 204 205 |
# File 'lib/super_awesome_resource_serializer.rb', line 197 def to_hash hash = HashWithIndifferentAccess.new serializable_fields(:getter).each do |field| if field.getter? hash[field.element] = wrap_object_for_hash(field.get(self), field.name) end end return hash end |
#to_json(json_options = nil) ⇒ Object
Serialize the object to JSON.
213 214 215 |
# File 'lib/super_awesome_resource_serializer.rb', line 213 def to_json ( = nil) to_hash.to_json() end |
#to_param ⇒ Object
Get the unique key used for lookups
223 224 225 |
# File 'lib/super_awesome_resource_serializer.rb', line 223 def to_param object.send(self.class.param_key || :id) end |
#to_xml(xml_options = {}) ⇒ Object
Serialize the object to XML.
208 209 210 |
# File 'lib/super_awesome_resource_serializer.rb', line 208 def to_xml ( = {}) to_hash.to_xml({:root => root_element, :dasherize => false}.reverse_merge()) end |
#to_yaml(yaml_options = {}) ⇒ Object
Serialize the object to YAML.
218 219 220 |
# File 'lib/super_awesome_resource_serializer.rb', line 218 def to_yaml ( = {}) remove_hash_indifferent_access(to_hash).to_yaml() end |
#update_with_json(json) ⇒ Object
Update the available fields in the object with a serialized representation of the object in JSON.
187 188 189 |
# File 'lib/super_awesome_resource_serializer.rb', line 187 def update_with_json (json) set_attributes(ActiveSupport::JSON.decode(json)) end |
#update_with_xml(xml) ⇒ Object
Update the available fields in the object with a serialized representation of the object in XML.
182 183 184 |
# File 'lib/super_awesome_resource_serializer.rb', line 182 def update_with_xml (xml) set_attributes(Hash.from_xml(xml)[root_element]) end |
#update_with_yaml(yaml) ⇒ Object
Update the available fields in the object with a serialized representation of the object in YAML.
192 193 194 |
# File 'lib/super_awesome_resource_serializer.rb', line 192 def update_with_yaml (yaml) set_attributes(YAML.load(yaml)) end |