Милен обнови решението на 01.12.2016 11:23 (преди около 8 години)
+class Helper
+ def self.hash_constains_in_hash(hash, searched)
+ eql = !hash[:id].nil? && !searched[:id].nil? && hash[:id] == searched[:id]
+ return true if eql
+
+ contains = true
+ searched.each do |key, value|
+ contains = false if hash[key] != value
+ end
+ contains
+ end
+
+ def self.hash_to_obj(obj, hash)
+ hash.each do |key, value|
+ setter_name = key.to_s + '='
+ obj.send(setter_name, value)
+ end
+ obj
+ end
+end
+
+class Store
+ attr_reader :incrementator
+
+ def initialize
+ @incrementator = 1
+ end
+
+ private
+
+ def insert_id_if_none(hash)
+ if hash[:id].nil?
+ hash[:id] = @incrementator
+ @incrementator += 1
+ end
+ end
+end
+
+class ArrayStore < Store
+ attr_reader :storage
+
+ def initialize
+ super
+ @storage = []
+ end
+
+ def create(hash)
+ insert_id_if_none(hash)
+ @storage << hash
+ end
+
+ def find(search_option)
+ result = []
+ @storage.each do |current|
+ result << current if Helper.hash_constains_in_hash(current, search_option)
+ end
+ result
+ end
+
+ def update(id, hash)
+ element = find(id: id).first
+ hash.each do |key, value|
+ element[key] = value
+ end
+ end
+
+ def delete(search_option)
+ elements = find(search_option)
+ @storage -= elements
+ end
+end
+
+class HashStore < Store
+ attr_reader :storage
+
+ def initialize
+ super
+ @storage = {}
+ end
+
+ def create(hash)
+ insert_id_if_none(hash)
+ @storage[hash[:id]] = hash
+ end
+
+ def find(search_option)
+ result = []
+ @storage.each do |_, current|
+ result << current if Helper.hash_constains_in_hash(current, search_option)
+ end
+ result
+ end
+
+ def update(id, hash)
+ element = find(id: id).first
+ hash.each do |key, value|
+ element[key] = value
+ end
+ end
+
+ def delete(search_option)
+ elements = find(search_option)
+ @storage = @storage.delete_if { |_, value| elements.include? value }
+ end
+end
+
+class DataModel
+ attr_reader :id
+ attr_reader :attributes_data
+
+ def initialize(data = nil)
+ unless data.nil?
+ data.each do |method_name, value|
+ setter_name = method_name.to_s + '='
+ public_send(setter_name, value) if respond_to? setter_name
+ # because id is private, no one should be modifying it
+ send(setter_name, value) if setter_name == 'id='
+ end
+ end
+ end
+
+ def self.attributes(*attr)
+ @attributes_data = []
+ attr.each do |x|
+ attr_accessor(x)
+ @attributes_data << x
+ end
+ end
+
+ def self.data_store(store)
+ @store = store
+ end
+
+ def self.where(search_option)
+ result = []
+ @store.find(search_option).each do |element|
+ result << Helper.hash_to_obj(self.new, element)
+ end
+ result
+ end
+
+ def save
+ hash = self_to_h
+ if @store.find(hash) == []
+ @store.create(hash)
+ else
+ @store.update(hash[:id], hash)
+ end
+ @id = hash[:id]
+ end
+
+ def delete
+ element = @store.find(self_to_h).first
+ @store.delete(element)
+ end
+
+ private
+
+ def self_to_h
+ result = {}
+ @attributes_data.each { |method| result[method] = public_send(method) }
+ result[:id] = @id unless @id.nil?
+ result
+ end
+
+ attr_writer :id
+end