Class: Fin::Model
- Inherits:
-
Object
- Object
- Fin::Model
- Includes:
- Enumerable
- Defined in:
- lib/fin/models/model.rb
Overview
Represents business domain model for a single item (Quote, Deal, Instrument, etc…) Currently it is only used to extract common functionality from record wrappers, down the road the goal is to add ActiveModel compatibility
Class Method Summary collapse
- .attribute_types ⇒ Object
-
.from_msg(msg) ⇒ Object
Unpacks attributes into appropriate Model subclass.
- .from_record(rec) ⇒ Object
- .model_class_id(value = nil) ⇒ Object
- .model_classes ⇒ Object
- .property(prop_hash) ⇒ Object
-
.to_msg(rec) ⇒ Object
Extracts attributes from record into a serializable format (Array) Returns an Array where 1st element is a model_class_id of our Model subclass, followed by a list of arguments to its initialize.
Instance Method Summary collapse
- #each ⇒ Object (also: #each_property)
- #index ⇒ Object
-
#initialize(*args) ⇒ Model
constructor
TODO: Builder pattern, to avoid args Array creation on each initialize?.
- #inspect(divider = ',') ⇒ Object
-
#to_msg ⇒ Object
Converts OBJECT attributes into a serializable format (Array) Returns an Array where 1st element is a model_class_id of our Model subclass, followed by a list of arguments to its initialize.
Constructor Details
#initialize(*args) ⇒ Model
TODO: Builder pattern, to avoid args Array creation on each initialize?
101 102 103 104 105 106 |
# File 'lib/fin/models/model.rb', line 101 def initialize *args @attributes = {} opts = args.last.is_a?(Hash) ? args.pop : {} each_with_index { |(name, _), i| send "#{name}=", args[i] } unless args.empty? opts.each { |name, value| send "#{name}=", value } end |
Class Method Details
.attribute_types ⇒ Object
9 10 11 |
# File 'lib/fin/models/model.rb', line 9 def self.attribute_types @attribute_types ||= (superclass.attribute_types.dup rescue {}) end |
.from_msg(msg) ⇒ Object
Unpacks attributes into appropriate Model subclass
81 82 83 84 |
# File 'lib/fin/models/model.rb', line 81 def self.from_msg msg class_id = msg.first model_classes[class_id].new *msg[1..-1] end |
.from_record(rec) ⇒ Object
76 77 78 |
# File 'lib/fin/models/model.rb', line 76 def self.from_record rec new *extract_attributes(rec) end |
.model_class_id(value = nil) ⇒ Object
13 14 15 16 17 18 19 20 |
# File 'lib/fin/models/model.rb', line 13 def self.model_class_id value = nil if value @model_class_id ||= value model_classes[@model_class_id] = self else @model_class_id end end |
.model_classes ⇒ Object
22 23 24 |
# File 'lib/fin/models/model.rb', line 22 def self.model_classes @model_classes ||= (superclass.model_classes rescue {}) #shared list for all subclasses end |
.property(prop_hash) ⇒ Object
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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/fin/models/model.rb', line 26 def self.property prop_hash prop_hash.each do |arg, type| aliases = [arg].flatten name = aliases.shift instance_eval do attribute_types[name.to_s] = type.to_s define_method(name) do @attributes[name] end define_method("#{name}=") do |value| @attributes[name] = value end aliases.each do |ali| alias_method "#{ali}", name alias_method "#{ali}=", "#{name}=" end end end # Using static calls, create class method extracting attributes from raw records attribute_extractor = attribute_types.map do |name, type| case type # TODO: Using indexes (...ByIndex) instead of names gives ~60% speed boost when /^i[14]/ "rec.GetValAsLong('#{name}')" when /^i8/ "rec.GetValAsVariant('#{name}')" when /^[df]/ "rec.GetValAsString('#{name}').to_f" when /^[c]/ "rec.GetValAsString('#{name}')" when /^[t]/ # "2009/12/01 12:35:44.785" => 20091201123544785 "rec.GetValAsVariant('#{name}')" else raise "Unrecognized attribute type: #{name} => #{type}" end end.join(",\n") extractor_body = "def self.extract_attributes rec [#{attribute_extractor}] end" # puts "In #{self}:, #{extractor_body" instance_eval extractor_body end |
.to_msg(rec) ⇒ Object
Extracts attributes from record into a serializable format (Array) Returns an Array where 1st element is a model_class_id of our Model subclass, followed by a list of arguments to its initialize. Class method!
89 90 91 |
# File 'lib/fin/models/model.rb', line 89 def self.to_msg rec extract_attributes(rec).unshift(model_class_id) end |
Instance Method Details
#each ⇒ Object Also known as: each_property
108 109 110 111 112 113 114 |
# File 'lib/fin/models/model.rb', line 108 def each if block_given? self.class.attribute_types.each { |name, _| yield [name, send(name)] } else self.class.attribute_types.map { |name, _| [name, send(name)].to_enum } end end |
#index ⇒ Object
131 132 133 |
# File 'lib/fin/models/model.rb', line 131 def index object_id # TODO: @repl_id? end |
#inspect(divider = ',') ⇒ Object
118 119 120 |
# File 'lib/fin/models/model.rb', line 118 def inspect divider=',' map { |property, value| "#{property}=#{value}" }.join(divider) end |
#to_msg ⇒ Object
Converts OBJECT attributes into a serializable format (Array) Returns an Array where 1st element is a model_class_id of our Model subclass, followed by a list of arguments to its initialize. Instance method!
96 97 98 |
# File 'lib/fin/models/model.rb', line 96 def to_msg inject([self.class.model_class_id]) { |array, (name, _)| array << send(name) } end |