Class: ModelBinding
- Inherits:
-
Object
- Object
- ModelBinding
- Includes:
- Observer
- Defined in:
- lib/command_handlers/models/model_binding.rb
Constant Summary collapse
- @@property_type_converters =
{ :undefined => lambda { |value| value }, :fixnum => lambda { |value| value.to_i }, :array => lambda { |value| value.to_a } }
Instance Attribute Summary collapse
-
#binding_options ⇒ Object
readonly
Returns the value of attribute binding_options.
-
#property_type ⇒ Object
readonly
Returns the value of attribute property_type.
Instance Method Summary collapse
- #add_observer(observer) ⇒ Object
- #base_model ⇒ Object
- #evaluate_options_property ⇒ Object
- #evaluate_property ⇒ Object
-
#initialize(base_model, property_name_expression, property_type = :undefined, binding_options = nil) ⇒ ModelBinding
constructor
A new instance of ModelBinding.
- #model ⇒ Object
-
#model_property_names ⇒ Object
Model representing nested property names e.g.
- #nested_model ⇒ Object
-
#nested_models ⇒ Object
e.g.
- #nested_property? ⇒ Boolean
-
#nested_property_name ⇒ Object
Final nested property name e.g.
-
#nested_property_names ⇒ Object
All nested property names e.g.
- #nested_property_observers_for(observer) ⇒ Object
- #options_property_name ⇒ Object
- #property_name ⇒ Object
- #property_name_expression ⇒ Object
- #update(value) ⇒ Object
Constructor Details
#initialize(base_model, property_name_expression, property_type = :undefined, binding_options = nil) ⇒ ModelBinding
Returns a new instance of ModelBinding.
12 13 14 15 16 17 18 |
# File 'lib/command_handlers/models/model_binding.rb', line 12 def initialize(base_model, property_name_expression, property_type = :undefined, = nil) property_type = :undefined if property_type.nil? @base_model = base_model @property_name_expression = property_name_expression @property_type = property_type = || {} end |
Instance Attribute Details
#binding_options ⇒ Object (readonly)
Returns the value of attribute binding_options.
6 7 8 |
# File 'lib/command_handlers/models/model_binding.rb', line 6 def end |
#property_type ⇒ Object (readonly)
Returns the value of attribute property_type.
6 7 8 |
# File 'lib/command_handlers/models/model_binding.rb', line 6 def property_type @property_type end |
Instance Method Details
#add_observer(observer) ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/command_handlers/models/model_binding.rb', line 77 def add_observer(observer) if nested_property? nested_property_observers = nested_property_observers_for(observer) nested_models.zip(nested_property_names).each do |model, property_name| model.extend ObservableModel unless model.is_a?(ObservableModel) model.add_observer(property_name, nested_property_observers[property_name]) unless model.has_observer?(property_name, nested_property_observers[property_name]) end else model.extend ObservableModel unless model.is_a?(ObservableModel) model.add_observer(property_name, observer) end end |
#base_model ⇒ Object
35 36 37 |
# File 'lib/command_handlers/models/model_binding.rb', line 35 def base_model @base_model end |
#evaluate_options_property ⇒ Object
96 97 98 |
# File 'lib/command_handlers/models/model_binding.rb', line 96 def model.send(property_name + "_options") end |
#evaluate_property ⇒ Object
93 94 95 |
# File 'lib/command_handlers/models/model_binding.rb', line 93 def evaluate_property model.send(property_name) end |
#model ⇒ Object
19 20 21 |
# File 'lib/command_handlers/models/model_binding.rb', line 19 def model nested_property? ? nested_model : base_model end |
#model_property_names ⇒ Object
Model representing nested property names e.g. property name expression “address.state” gives [:address]
53 54 55 |
# File 'lib/command_handlers/models/model_binding.rb', line 53 def model_property_names nested_property_names[0...-1] end |
#nested_model ⇒ Object
32 33 34 |
# File 'lib/command_handlers/models/model_binding.rb', line 32 def nested_model nested_models.last end |
#nested_models ⇒ Object
e.g. person.address.state returns [person, person.address]
23 24 25 26 27 28 29 30 31 |
# File 'lib/command_handlers/models/model_binding.rb', line 23 def nested_models @nested_models = [base_model] model_property_names.reduce(base_model) do |reduced_model, nested_model_property_name| reduced_model.send(nested_model_property_name).tap do |new_reduced_model| @nested_models << new_reduced_model end end @nested_models end |
#nested_property? ⇒ Boolean
56 57 58 |
# File 'lib/command_handlers/models/model_binding.rb', line 56 def nested_property? property_name_expression.include?(".") end |
#nested_property_name ⇒ Object
Final nested property name e.g. property name expression “address.state” gives :state
48 49 50 |
# File 'lib/command_handlers/models/model_binding.rb', line 48 def nested_property_name nested_property_names.last end |
#nested_property_names ⇒ Object
All nested property names e.g. property name expression “address.state” gives [:address, :state]
43 44 45 |
# File 'lib/command_handlers/models/model_binding.rb', line 43 def nested_property_names property_name_expression.split(".") end |
#nested_property_observers_for(observer) ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/command_handlers/models/model_binding.rb', line 62 def nested_property_observers_for(observer) @nested_property_observers_collection ||= {} unless @nested_property_observers_collection.has_key?(observer) @nested_property_observers_collection[observer] = nested_property_names.reduce({}) do |output, property_name| output.merge( property_name => BlockObserver.new do |changed_value| # Ensure reattaching observers when a higher level nested property is updated (e.g. person.address changes reattaches person.address.street observer) add_observer(observer) observer.update(evaluate_property) end ) end end @nested_property_observers_collection[observer] end |
#options_property_name ⇒ Object
99 100 101 |
# File 'lib/command_handlers/models/model_binding.rb', line 99 def self.property_name + "_options" end |
#property_name ⇒ Object
38 39 40 |
# File 'lib/command_handlers/models/model_binding.rb', line 38 def property_name nested_property? ? nested_property_name : property_name_expression end |
#property_name_expression ⇒ Object
59 60 61 |
# File 'lib/command_handlers/models/model_binding.rb', line 59 def property_name_expression @property_name_expression end |
#update(value) ⇒ Object
89 90 91 92 |
# File 'lib/command_handlers/models/model_binding.rb', line 89 def update(value) converted_value = @@property_type_converters[@property_type].call(value) model.send(property_name + "=", converted_value) unless evaluate_property == converted_value end |