Class: AeEasy::Core::SmartCollection
- Inherits:
-
Array
- Object
- Array
- AeEasy::Core::SmartCollection
- Defined in:
- lib/ae_easy/core/smart_collection.rb
Overview
Smart collection capable to avoid duplicates on insert by matching id
defined fields along events.
Constant Summary collapse
- EVENTS =
Implemented event list.
[ :before_defaults, :before_match, :before_insert, :after_insert ]
Instance Attribute Summary collapse
-
#defaults ⇒ Object
readonly
Default fields values.
-
#key_fields ⇒ Object
readonly
Key fields, analog to primary keys.
Instance Method Summary collapse
-
#<<(item) ⇒ Object
Add/remplace an item avoiding duplicates.
-
#apply_defaults(item) ⇒ Hash
Apply default values into item.
-
#bind_event(key, &block) ⇒ Object
Add event binding by key and block.
-
#call_event(key, default = nil, *args) ⇒ Object
Call an event.
-
#events ⇒ Object
Asigned events.
-
#find_match(filter) ⇒ Hash|nil
Find an item by matching filter keys.
-
#initialize(key_fields, opts = {}) ⇒ SmartCollection
constructor
Initialize collection.
-
#match_keys?(item_a, item_b) ⇒ Boolean
Check whenever two items keys match.
Constructor Details
#initialize(key_fields, opts = {}) ⇒ SmartCollection
Defaults will apply to missing fields and null values only.
Initialize collection
50 51 52 53 54 55 |
# File 'lib/ae_easy/core/smart_collection.rb', line 50 def initialize key_fields, opts = {} @key_fields = key_fields || [] @defaults = opts[:defaults] || {} super 0 (opts[:values] || []).each{|item| self << item} end |
Instance Attribute Details
#defaults ⇒ Object (readonly)
Default fields values. Apply to missing fields and null values.
17 18 19 |
# File 'lib/ae_easy/core/smart_collection.rb', line 17 def defaults @defaults end |
#key_fields ⇒ Object (readonly)
Key fields, analog to primary keys.
15 16 17 |
# File 'lib/ae_easy/core/smart_collection.rb', line 15 def key_fields @key_fields end |
Instance Method Details
#<<(item) ⇒ Object
Add/remplace an item avoiding duplicates
224 225 226 227 228 229 230 231 232 233 |
# File 'lib/ae_easy/core/smart_collection.rb', line 224 def << item item = call_event :before_defaults, item, item apply_defaults item item = call_event :before_match, item, item match = find_match item item = call_event :before_insert, item, item, match delete match unless match.nil? result = super(item) call_event :after_insert, result, item, match end |
#apply_defaults(item) ⇒ Hash
Apply default values into item.
203 204 205 206 207 208 |
# File 'lib/ae_easy/core/smart_collection.rb', line 203 def apply_defaults item defaults.each do |key, value| next unless item[key].nil? item[key] = value.respond_to?(:call) ? value.call(item) : value end end |
#bind_event(key, &block) ⇒ Object
Some events will expect a return value to replace item on insertion:
-
`before_match`
-
`before_defaults`
-
`before_insert`
Add event binding by key and block.
161 162 163 164 165 166 |
# File 'lib/ae_easy/core/smart_collection.rb', line 161 def bind_event key, &block unless EVENTS.include? key raise ArgumentError.new("Unknown event '#{key}'") end (events[key] ||= []) << block end |
#call_event(key, default = nil, *args) ⇒ Object
Call an event
174 175 176 177 178 179 |
# File 'lib/ae_easy/core/smart_collection.rb', line 174 def call_event key, default = nil, *args return default if events[key].nil? result = nil events[key].each{|event| result = event.call self, *args} result.nil? ? default : result end |
#events ⇒ Object
Asigned events.
59 60 61 |
# File 'lib/ae_easy/core/smart_collection.rb', line 59 def events @events ||= {} end |
#find_match(filter) ⇒ Hash|nil
Warning: It uses table scan to filter and will be slow.
Find an item by matching filter keys
217 218 219 220 221 |
# File 'lib/ae_easy/core/smart_collection.rb', line 217 def find_match filter self.find do |item| match_keys? item, filter end end |
#match_keys?(item_a, item_b) ⇒ Boolean
Check whenever two items keys match.
187 188 189 190 191 192 193 194 195 |
# File 'lib/ae_easy/core/smart_collection.rb', line 187 def match_keys? item_a, item_b return false if key_fields.nil? || key_fields.count < 1 return true if item_a.nil? && item_b.nil? return false if item_a.nil? || item_b.nil? key_fields.each do |key| return false if item_a[key] != item_b[key] end true end |