Решение на Пета задача - DataModel от Даниела Русева

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

Към профила на Даниела Русева

Резултати

  • 5 точки от тестове
  • 0 бонус точки
  • 5 точки общо
  • 22 успешни тест(а)
  • 3 неуспешни тест(а)

Код

module ClassMethods
attr_accessor :attributes_array
attr_accessor :storage
def attributes(*columns)
if !columns.empty?
create_find_by(columns.to_a)
DataModel.attributes_array = columns.to_a
else
DataModel.attributes_array
end
end
def data_store(storage = nil)
if storage != nil
DataModel.storage = storage
else
DataModel.storage
end
end
def where(query)
query.each do |k, _|
raise DataModel::UnknownAttributeError, 'Unknown attribute :' + k
.to_s unless DataModel.attributes_array.include?(k)
end
result = []
DataModel.storage.find(query).each do |n|
result << self.new(n)
result.last.id = n[:id]
end
result
end
def create_find_by(attributes)
attributes.each do |x|
self.class.send :define_method, "find_by_" + x.to_s do |value|
result = []
DataModel.storage.find(x.to_s.to_sym => value).each do |n|
result << self.new(n)
result.last.id = n[:id]
end
result
end
end
end
end
class DataModel
class DeleteUnsavedRecordError < StandardError
end
class UnknownAttributeError < StandardError
end
extend ClassMethods
@id
attr_accessor :id
def initialize(values = {})
DataModel.attributes_array.each do |x|
singleton_class.class_eval { attr_accessor x.to_s }
send(x.to_s + '=', nil)
end
values.each do |k, v|
send(k.to_s + '=', v) if DataModel.attributes_array.include?(k)
end
end
def save
if @id == nil
@id = DataModel.storage.max_id += 1
hash_attributes = Hash[DataModel
.attributes_array.each.map { |k| [k, send(k.to_s)] }].merge!(id: @id)
DataModel.storage.create(hash_attributes)
else
hash_attributes = Hash[DataModel
.attributes_array.each.map { |k| [k, send(k.to_s)] }].merge!(id: @id)
DataModel.storage.update(@id, hash_attributes)
end
end
def delete
if !DataModel.storage.find(id: @id).empty?
DataModel.storage.delete({id: @id})
else
raise DataModel::DeleteUnsavedRecordError
end
end
def ==(other)
if !(other.class == self.class)
false
elsif !DataModel.storage.find(id: @id).empty? && !DataModel
.storage.find(id: other.id).empty? && (@id == other.id)
true
elsif self.object_id == other.object_id
true
end
end
end
class ArrayStore
def initialize
@storage = []
@max_id = 0
end
def create(record)
@storage << record
end
def find(query)
@storage.select { |n| n.merge(query) == n }
end
def update(id, attributes)
idx = 0
@storage.each_with_index do |n, index|
idx = index if n[:id] == id
end
attributes.each do |k, v|
@storage[idx][k] = v if @storage[idx].key?(k)
end
end
def delete(query)
@storage.delete_if { |n| n.merge(query) == n }
end
attr_reader :storage
attr_accessor :max_id
end
class HashStore
def initialize
@storage = {}
@max_id = 0
end
def create(record)
@storage[record[:id]] = record
end
def find(query)
@storage.select { |_, v| v.merge(query) == v }.values
end
def update(id, attributes)
attributes.each do |k, v|
@storage[id][k] = v if @storage[id].key?(k)
end
end
def delete(query)
@storage.delete_if { |_, v| v.merge(query) == v }
end
attr_reader :storage
attr_accessor :max_id
end

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

.......F....FF...........

Failures:

  1) DataModel equality comparison compares by id if both records are saved
     Failure/Error: modified_ivan = user_model.where(id: ivan.id).first
     DataModel::UnknownAttributeError:
       Unknown attribute :id
     # /tmp/d20161202-15620-qfqinv/solution.rb:23:in `block in where'
     # /tmp/d20161202-15620-qfqinv/solution.rb:22:in `each'
     # /tmp/d20161202-15620-qfqinv/solution.rb:22:in `where'
     # /tmp/d20161202-15620-qfqinv/spec.rb:102:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  2) DataModel.where raises an error if the query is by an unknown key
     Failure/Error: expect { user_model.where(middle_name: 'Ivanov') }.to raise_error(
       expected DataModel::UnknownAttributeError with "Unknown attribute middle_name", got #<DataModel::UnknownAttributeError: Unknown attribute :middle_name> with backtrace:
         # /tmp/d20161202-15620-qfqinv/solution.rb:23:in `block in where'
         # /tmp/d20161202-15620-qfqinv/solution.rb:22:in `each'
         # /tmp/d20161202-15620-qfqinv/solution.rb:22:in `where'
         # /tmp/d20161202-15620-qfqinv/spec.rb:143:in `block (4 levels) in <top (required)>'
         # /tmp/d20161202-15620-qfqinv/spec.rb:143:in `block (3 levels) in <top (required)>'
         # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
         # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'
     # /tmp/d20161202-15620-qfqinv/spec.rb:143:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  3) DataModel#delete deletes only the record for which it is called
     Failure/Error: ivan.delete
     ArgumentError:
       wrong number of arguments (given 0, expected 1)
     # /tmp/d20161202-15620-qfqinv/spec.rb:156:in `delete'
     # /tmp/d20161202-15620-qfqinv/spec.rb:156:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

Finished in 0.02936 seconds
25 examples, 3 failures

Failed examples:

rspec /tmp/d20161202-15620-qfqinv/spec.rb:92 # DataModel equality comparison compares by id if both records are saved
rspec /tmp/d20161202-15620-qfqinv/spec.rb:142 # DataModel.where raises an error if the query is by an unknown key
rspec /tmp/d20161202-15620-qfqinv/spec.rb:151 # DataModel#delete deletes only the record for which it is called

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

Даниела обнови решението на 01.12.2016 22:10 (преди над 7 години)

+module ClassMethods
+ attr_accessor :attributes_array
+ attr_accessor :storage
+ def attributes(*columns)
+ if !columns.empty?
+ create_find_by(columns.to_a)
+ DataModel.attributes_array = columns.to_a
+ else
+ DataModel.attributes_array
+ end
+ end
+
+ def data_store(storage = nil)
+ if storage != nil
+ DataModel.storage = storage
+ else
+ DataModel.storage
+ end
+ end
+
+ def where(query)
+ query.each do |k, _|
+ raise DataModel::UnknownAttributeError, 'Unknown attribute :' + k
+ .to_s unless DataModel.attributes_array.include?(k)
+ end
+ result = []
+ DataModel.storage.find(query).each do |n|
+ result << self.new(n)
+ result.last.id = n[:id]
+ end
+ result
+ end
+
+ def create_find_by(attributes)
+ attributes.each do |x|
+ self.class.send :define_method, "find_by_" + x.to_s do |value|
+ result = []
+ DataModel.storage.find(x.to_s.to_sym => value).each do |n|
+ result << self.new(n)
+ result.last.id = n[:id]
+ end
+ result
+ end
+ end
+ end
+end
+
+class DataModel
+ class DeleteUnsavedRecordError < StandardError
+ end
+
+ class UnknownAttributeError < StandardError
+ end
+
+ extend ClassMethods
+
+ @id
+ attr_accessor :id
+
+ def initialize(values = {})
+ DataModel.attributes_array.each do |x|
+ singleton_class.class_eval { attr_accessor x.to_s }
+ send(x.to_s + '=', nil)
+ end
+ values.each do |k, v|
+ send(k.to_s + '=', v) if DataModel.attributes_array.include?(k)
+ end
+ end
+
+ def save
+ if @id == nil
+ @id = DataModel.storage.max_id += 1
+ hash_attributes = Hash[DataModel
+ .attributes_array.each.map { |k| [k, send(k.to_s)] }].merge!(id: @id)
+ DataModel.storage.create(hash_attributes)
+ else
+ hash_attributes = Hash[DataModel
+ .attributes_array.each.map { |k| [k, send(k.to_s)] }].merge!(id: @id)
+ DataModel.storage.update(@id, hash_attributes)
+ end
+ end
+
+ def delete
+ if !DataModel.storage.find(id: @id).empty?
+ DataModel.storage.delete({id: @id})
+ else
+ raise DataModel::DeleteUnsavedRecordError
+ end
+ end
+
+ def ==(other)
+ if !(other.class == self.class)
+ false
+ elsif !DataModel.storage.find(id: @id).empty? && !DataModel
+ .storage.find(id: other.id).empty? && (@id == other.id)
+ true
+ elsif self.object_id == other.object_id
+ true
+ end
+ end
+end
+
+class ArrayStore
+ def initialize
+ @storage = []
+ @max_id = 0
+ end
+
+ def create(record)
+ @storage << record
+ end
+
+ def find(query)
+ @storage.select { |n| n.merge(query) == n }
+ end
+
+ def update(id, attributes)
+ idx = 0
+ @storage.each_with_index do |n, index|
+ idx = index if n[:id] == id
+ end
+ attributes.each do |k, v|
+ @storage[idx][k] = v if @storage[idx].key?(k)
+ end
+ end
+
+ def delete(query)
+ @storage.delete_if { |n| n.merge(query) == n }
+ end
+
+ attr_reader :storage
+ attr_accessor :max_id
+end
+
+class HashStore
+ def initialize
+ @storage = {}
+ @max_id = 0
+ end
+
+ def create(record)
+ @storage[record[:id]] = record
+ end
+
+ def find(query)
+ @storage.select { |_, v| v.merge(query) == v }.values
+ end
+
+ def update(id, attributes)
+ attributes.each do |k, v|
+ @storage[id][k] = v if @storage[id].key?(k)
+ end
+ end
+
+ def delete(query)
+ @storage.delete_if { |_, v| v.merge(query) == v }
+ end
+
+ attr_reader :storage
+ attr_accessor :max_id
+end