Module RubyAMF::Model
In: lib/rubyamf/model.rb

Simply include in your ruby object to enable advanced serialization features like an in-model mapping API, customizable initialization after deserialization, scoped property configuration for serialization, and several other things. See RubyAMF::Model::ClassMethods for details of in-model mapping API.

Example:

  class SerializableObject
    include RubyAMF::Model

    as_class "com.rubyamf.ASObject"
    map_amf :only => "prop_a"

    attr_accessor :prop_a, :prop_b
  end

Integration

If the object you include RubyAMF::Model into implements attributes and attributes=, those two methods will be automatically used to determine serializable properties and to set them after deserialization. If you do not implement those methods, attributes will be guessed by going through all methods that don‘t take arguments, and attribute setters will be used rather than attributes=.

For most ORMs, the provided rubyamf_init, rubyamf_hash, and rubyamf_retrieve_association should work correctly. However, they can be overridden to provide custom behavior if the default has issues with the ORM you are using. See RubyAMF::Rails::Model for an example of ORM-specific customization.

Methods

Classes and Modules

Module RubyAMF::Model::ClassMethods

Public Instance methods

Like serializable_hash, rubyamf_hash returns a hash for serialization calculated from the given options. Supported options are :only, :except, :methods, and :include. This method is automatically called by RubyAMF::ClassMapping on serialization with the pre-configured options for whatever the current scope is.

[Source]

     # File lib/rubyamf/model.rb, line 132
132:     def rubyamf_hash options=nil
133:       # Process options
134:       options ||= {}
135:       only = Array.wrap(options[:only]).map(&:to_s)
136:       except = Array.wrap(options[:except]).map(&:to_s)
137:       method_names = []
138:       Array.wrap(options[:methods]).each do |name|
139:         method_names << name.to_s if respond_to?(name)
140:       end
141: 
142:       # Get list of attributes
143:       if respond_to?(:attributes)
144:         attrs = send(:attributes)
145:       else
146:         attrs = {}
147:         ignored_props = Object.new.public_methods
148:         (self.public_methods - ignored_props).each do |method_name|
149:           # Add them to the attrs hash if they take no arguments
150:           method_def = self.method(method_name)
151:           attrs[method_name.to_s] = send(method_name) if method_def.arity == 0
152:         end
153:       end
154:       attribute_names = attrs.keys.sort
155:       if only.any?
156:         attribute_names &= only
157:       elsif except.any?
158:         attribute_names -= except
159:       end
160: 
161:       # Remove ignore_fields unless in only
162:       RubyAMF.configuration.ignore_fields.each do |field|
163:         attribute_names.delete(field) unless only.include?(field)
164:       end
165: 
166:       # Build hash from attributes and methods
167:       hash = {}
168:       attribute_names.each {|name| hash[name] = attrs[name]}
169:       method_names.each {|name| hash[name] = send(name)}
170: 
171:       # Add associations using ActiveRecord::Serialization style options
172:       # processing
173:       if include_associations = options.delete(:include)
174:         # Process options
175:         base_only_or_except = {:except => options[:except], :only => options[:only]}
176:         include_has_options = include_associations.is_a?(Hash)
177:         associations = include_has_options ? include_associations.keys : Array.wrap(include_associations)
178: 
179:         # Call to_amf on each object in the association, passing processed options
180:         associations.each do |association|
181:           records = rubyamf_retrieve_association(association)
182:           if records
183:             opts = include_has_options ? include_associations[association] : nil
184:             if records.is_a?(Enumerable)
185:               hash[association.to_s] = records.map {|r| opts.nil? ? r : r.to_amf(opts)}
186:             else
187:               hash[association.to_s] = opts.nil? ? records : records.to_amf(opts)
188:             end
189:           end
190:         end
191: 
192:         options[:include] = include_associations
193:       end
194: 
195:       hash
196:     end

Populates the object after deserialization. By default it calls initialize, calls setters for keys not in attributes, and calls attributes= for the remaining properties if it‘s implemented. Override if necessary to support your ORM.

[Source]

     # File lib/rubyamf/model.rb, line 98
 98:     def rubyamf_init props, dynamic_props = nil
 99:       initialize # warhammerkid: Call initialize by default - good decision?
100: 
101:       props.merge!(dynamic_props) if dynamic_props
102:       if respond_to?(:attributes=)
103:         attrs = self.attributes
104:         rubyamf_set_non_attributes props, attrs
105:         self.attributes = props # Populate using attributes setter
106:       else
107:         rubyamf_set_non_attributes props, {} # Calls setters for all props it finds setters for
108:       end
109:     end

Override if necessary to support your ORM‘s system of retrieving objects in an association.

[Source]

     # File lib/rubyamf/model.rb, line 200
200:     def rubyamf_retrieve_association association
201:       # Naive implementation that should work for most cases without
202:       # need for overriding
203:       send(association)
204:     end

Calls setters for all keys in the given hash not found in the base attributes hash and deletes those keys from the hash. Performs some simple checks on the keys to hopefully prevent more private setters from being called.

[Source]

     # File lib/rubyamf/model.rb, line 114
114:     def rubyamf_set_non_attributes attrs, base_attrs
115:       not_attributes = attrs.keys.select {|k| !base_attrs.include?(k)}
116:       not_attributes.each do |k|
117:         setter = "#{k}="
118:         next if setter !~ /^[a-z][A-Za-z0-9_]+=/ # Make sure setter doesn't start with capital, dollar, or underscore to make this safer
119:         if respond_to?(setter)
120:           send(setter, attrs.delete(k))
121:         else
122:           RubyAMF.logger.warn("RubyAMF: Cannot call setter for non-attribute on #{self.class.name}: #{k}")
123:         end
124:       end
125:     end

Stores the given options and object in an IntermediateObject so that the default serialization mapping options can be overriden if necessary.

[Source]

     # File lib/rubyamf/model.rb, line 208
208:     def to_amf options=nil
209:       RubyAMF::IntermediateObject.new(self, options)
210:     end

[Validate]