Решение на Пета задача - DataModel от Георги Ангелов

Обратно към всички решения

Към профила на Георги Ангелов

Резултати

  • 6 точки от тестове
  • 0 бонус точки
  • 6 точки общо
  • 25 успешни тест(а)
  • 0 неуспешни тест(а)

Код

class HashStore
attr_reader :storage
def initialize
@storage = {}
@id_counter = 0
end
def next_id
@id_counter += 1
end
def create(record)
@storage[record[:id]] = record
end
def find(query)
@storage.values.select do |record|
query.all? { |key, value| record[key] == value }
end
end
def delete(query)
find(query).each { |record| @storage.delete(record[:id]) }
end
def update(id, record)
return unless @storage.key? id
@storage[id] = record
end
end
class ArrayStore
attr_reader :storage
def initialize
@storage = []
@id_counter = 0
end
def next_id
@id_counter += 1
end
def create(record)
@storage << record
end
def find(query)
@storage.select { |record| match_record? query, record }
end
def delete(query)
@storage.reject! { |record| match_record? query, record }
end
def update(id, record)
index = @storage.find_index { |record| record[:id] == id }
return unless index
@storage[index] = record
end
private
def match_record?(query, record)
query.all? { |key, value| record[key] == value }
end
end
module DataModelClassMethods
def attributes(*attributes)
return @attributes if attributes.empty?
@attributes = attributes + [:id]
@attributes.each do |attribute|
define_singleton_method "find_by_#{attribute}" do |value|
where(attribute => value)
end
define_method(attribute) { @attributes[attribute] }
define_method("#{attribute}=") { |value| @attributes[attribute] = value }
end
end
def data_store(store = nil)
return @data_store unless store
@data_store = store
end
def where(query)
query.keys.reject { |key| @attributes.include? key }.each do |key|
raise DataModel::UnknownAttributeError.new(key)
end
map_to_model_instances data_store.find(query)
end
def all
where({})
end
private
def map_to_model_instances(records)
records.map { |record| new(record) }
end
end
class DataModel
class UnknownAttributeError < ArgumentError
def initialize(attribute_name)
super "Unknown attribute #{attribute_name}"
end
end
class DeleteUnsavedRecordError < StandardError
end
extend DataModelClassMethods
def initialize(attributes = {})
@attributes = attributes.select { |key, _| self.class.attributes.include? key }
end
def save
if id
data_store.update(id, @attributes)
else
self.id = data_store.next_id
data_store.create(@attributes)
end
self
end
def delete
raise DeleteUnsavedRecordError.new unless id
data_store.delete(id: id)
end
def ==(other)
return id == other.id if id && other.id
equal? other
end
private
def data_store
self.class.data_store
end
end

Лог от изпълнението

.........................

Finished in 0.0242 seconds
25 examples, 0 failures

История (1 версия и 0 коментара)

Георги обнови решението на 23.11.2016 22:59 (преди над 7 години)

+class HashStore
+ attr_reader :storage
+
+ def initialize
+ @storage = {}
+ @id_counter = 0
+ end
+
+ def next_id
+ @id_counter += 1
+ end
+
+ def create(record)
+ @storage[record[:id]] = record
+ end
+
+ def find(query)
+ @storage.values.select do |record|
+ query.all? { |key, value| record[key] == value }
+ end
+ end
+
+ def delete(query)
+ find(query).each { |record| @storage.delete(record[:id]) }
+ end
+
+ def update(id, record)
+ return unless @storage.key? id
+
+ @storage[id] = record
+ end
+end
+
+class ArrayStore
+ attr_reader :storage
+
+ def initialize
+ @storage = []
+ @id_counter = 0
+ end
+
+ def next_id
+ @id_counter += 1
+ end
+
+ def create(record)
+ @storage << record
+ end
+
+ def find(query)
+ @storage.select { |record| match_record? query, record }
+ end
+
+ def delete(query)
+ @storage.reject! { |record| match_record? query, record }
+ end
+
+ def update(id, record)
+ index = @storage.find_index { |record| record[:id] == id }
+ return unless index
+
+ @storage[index] = record
+ end
+
+ private
+
+ def match_record?(query, record)
+ query.all? { |key, value| record[key] == value }
+ end
+end
+
+module DataModelClassMethods
+ def attributes(*attributes)
+ return @attributes if attributes.empty?
+
+ @attributes = attributes + [:id]
+
+ @attributes.each do |attribute|
+ define_singleton_method "find_by_#{attribute}" do |value|
+ where(attribute => value)
+ end
+
+ define_method(attribute) { @attributes[attribute] }
+ define_method("#{attribute}=") { |value| @attributes[attribute] = value }
+ end
+ end
+
+ def data_store(store = nil)
+ return @data_store unless store
+
+ @data_store = store
+ end
+
+ def where(query)
+ query.keys.reject { |key| @attributes.include? key }.each do |key|
+ raise DataModel::UnknownAttributeError.new(key)
+ end
+
+ map_to_model_instances data_store.find(query)
+ end
+
+ def all
+ where({})
+ end
+
+ private
+
+ def map_to_model_instances(records)
+ records.map { |record| new(record) }
+ end
+end
+
+class DataModel
+ class UnknownAttributeError < ArgumentError
+ def initialize(attribute_name)
+ super "Unknown attribute #{attribute_name}"
+ end
+ end
+
+ class DeleteUnsavedRecordError < StandardError
+ end
+
+ extend DataModelClassMethods
+
+ def initialize(attributes = {})
+ @attributes = attributes.select { |key, _| self.class.attributes.include? key }
+ end
+
+ def save
+ if id
+ data_store.update(id, @attributes)
+ else
+ self.id = data_store.next_id
+ data_store.create(@attributes)
+ end
+
+ self
+ end
+
+ def delete
+ raise DeleteUnsavedRecordError.new unless id
+
+ data_store.delete(id: id)
+ end
+
+ def ==(other)
+ return id == other.id if id && other.id
+
+ equal? other
+ end
+
+ private
+
+ def data_store
+ self.class.data_store
+ end
+end