Стамен обнови решението на 29.11.2016 22:25 (преди около 8 години)
+class ArrayStore
+ def initialize
+ @array = []
+ end
+
+ def storage
+ @array
+ end
+
+ alias_method :format_for_search, :storage
+
+ def create(data = {})
+ @array.push data
+ end
+
+ def find(data = {})
+ storage.select do |e|
+ (e.to_a & data.to_a) == data.to_a
+ end
+ end
+
+ def update(id, newdata = {})
+ @array.each_with_index do |e, i|
+ @array[i] = newdata if e[:id] == id
+ end
+ end
+
+ def delete(data = {})
+ @array.length.times do
+ @array.each_with_index { |e, i| @array.delete_at(i) if e == data }
+ end
+ end
+end
+
+class HashStore
+ def initialize
+ @hash = {}
+ end
+
+ def format_for_search
+ res = []
+ @hash.each { |_, v| res << v }
+ res
+ end
+
+ def storage
+ @hash
+ end
А защо не използваш attr_reader
? :)
E нали самия метод трябва да се казва storage.
+
+ def create(data = {})
+ @hash[data[:id]] = data
+ end
+
+ def find(data = {})
+ res = []
+ @hash.each { |_, v| res << v if (v.to_a & data.to_a) == data.to_a }
+ res
+ end
+
+ def update(id, newdata = {})
+ @hash.each { |k, _| @hash[k] = newdata if k == id }
+ end
+
+ def delete(data = {})
+ @hash.length.times do
+ @hash.each { |k, v| @hash.delete(k) if v == data }
+ end
+ end
+end
+
+module ClassMethods
+ def attributes(*att)
+ if !@arr
+ @arr = att
+ att.each do |var|
+ work_with_attribute(var)
+ end
+ else
+ @arr
Тук и на още много места имаш съкращения - това е изключително вреден навик - откажи се от него.
+ end
+ end
+
+ def work_with_attribute(var)
+ attr_accessor var
+ define_singleton_method "find_by_#{var}" do |arg|
+ where({"#{var}": arg})
+ end
+ end
+
+ def data_store(*data)
+ if !@store
+ @store = data[0]
+ else
+ @store
+ end
+ end
+
+ def where(** attributes2)
+ attributes2.each do |name, _|
+ raise UnknownAttributeError unless @arr.include?(name)
+ end
+ seek = attributes2.to_a
+ @store.format_for_search.select do |e|
+ (e.to_a & seek) == seek
+ end.map { |k| self.new(k.to_hash) }
+ end
+end
+
+class DataModel
+
+ class DeleteUnsavedRecordError < StandardError
+ end
+ class UnknownAttributeError < StandardError
+ end
+
+ attr_accessor :arr, :store, :id
+
+ extend ClassMethods
+
+ def initialize(**attributes2)
+ @id = nil
+ self.class.attributes.each { |e| send "#{e}=", nil }
+ attributes2.each do |name, value|
+ send "#{name}=", value if self.class.attributes.include?(name)
+ end
+ end
+
+ def ==(other)
+ bool_one = self.class == other.class && id == other.id && id != nil
+ bool_two = equal?other
+ bool_one || bool_two
+ end
+
+ def delete
+ raise DeleteUnsavedRecordError if self.class.data_store.find(to_hash).empty?
+ self.class.data_store.delete(to_hash)
+ @id = nil
+ end
+
+ def save
+ if !@id
Старай се условията винаги да са първо с положителния случай.
if !something
else
end
се чете по-трудно от
if something
else
end
+ free_id = 0
+ ObjectSpace.each_object(self.class).to_a.select { |a| a.id != nil }.each do |e|
Защо правиш това?
- id-тата не трябва да работят така - виж пак в условието
- Инстанциите на модела може да ги няма в паметта, но да са записани в store-а.
+ free_id = e.id if e.id > free_id
+ end
+ @id = free_id + 1
+ self.class.data_store.create(to_hash)
+ else
+ self.class.data_store.update(@id, to_hash)
+ end
+ end
+
+ def to_hash
+ values = []
+ (self.class.attributes << :id).each_with_index do |name, i|
+ values[i] = []
+ values[i] << name
+ values[i].push send name.to_s
+ end
+ values = values.to_h
+ end
+end