Skip to content

Instantly share code, notes, and snippets.

@forresty
Created July 18, 2017 10:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save forresty/7f49ff6613e3e9423aba044d3127096d to your computer and use it in GitHub Desktop.
Save forresty/7f49ff6613e3e9423aba044d3127096d to your computer and use it in GitHub Desktop.
class BaseModel
attr_accessor :id
def initialize(attributes = {})
@id = attributes[:id]
end
end
# require_relative '../models/object'
class BaseRepository
def initialize(csv_file)
@csv_file = csv_file
@elements = []
load_csv if File.exist?(@csv_file)
@next_id = @elements.empty? ? 1 : @elements.last.id + 1
end
def all
@elements
end
def find(object_id)
@elements.find { |object| object.id == object_id }
end
def add(new_object)
@elements << new_object
new_object.id = @next_id
@next_id += 1
save_csv
end
private
def serialized_attributes
raise 'should overwrite'
end
def serialize(element)
# %w{ id name price }
# => [element.id, element.name, element.price]
serialized_attributes.map { |attr| element.send(attr) }
end
def deserialize(row)
raise 'should overwrite'
end
def save_csv
CSV.open(@csv_file, 'wb') do |csv|
csv << serialized_attributes
@elements.each do |element|
csv << serialize(element)
end
end
end
def load_csv
csv_options = {
headers: :first_row,
header_converters: :symbol
}
CSV.foreach(@csv_file, csv_options) do |row|
@elements << deserialize(row)
end
end
end
class BaseView
def initialize(element_class)
@element_class = element_class
end
def display(elements)
elements.each do |element|
puts element.to_s
end
end
def ask_for(stuff)
puts "enter #{stuff} for new #{@element_class.name.downcase}:"
print '> '
gets.chomp
end
end
require_relative 'base_model'
class Customer < BaseModel
attr_reader :name, :address
def initialize(attributes = {})
super
@name = attributes[:name]
@address = attributes[:address]
end
def to_s
"#{id} - #{name} - #{address}"
end
end
require_relative '../models/customer'
require_relative 'base_repository'
class CustomerRepository < BaseRepository
private
def serialized_attributes
%w{ id name address }
end
def deserialize(row)
row[:id] = row[:id].to_i
row[:address] = row[:address]
Customer.new(row)
end
end
require_relative '../models/customer'
require_relative '../views/customers_view'
class CustomersController
def initialize(customer_repo)
@customer_repo = customer_repo
@view = BaseView.new(Customer)
end
def add
name = @view.ask_for(:name)
address = @view.ask_for(:address)
new_customer = Customer.new(name: name, address: address)
@customer_repo.add(new_customer)
end
def list
customers = @customer_repo.all
@view.display(customers)
end
end
require_relative 'base_view'
class CustomersView < BaseView
end
require_relative 'base_model'
class Meal < BaseModel
attr_reader :name, :price
def initialize(attributes = {})
super
@name = attributes[:name]
@price = attributes[:price]
end
end
require_relative '../models/meal'
require_relative 'base_repository'
class MealRepository < BaseRepository
private
def serialized_attributes
%w{ id name price }
end
def deserialize(row)
row[:id] = row[:id].to_i
row[:price] = row[:price].to_i
Meal.new(row)
end
end
require_relative '../models/meal'
require_relative '../views/meals_view'
class MealsController
def initialize(meal_repo)
@meal_repo = meal_repo
@view = MealsView.new
end
def list
meals = @meal_repo.all
@view.display(meals)
end
def add
name = @view.ask_for(:name)
price = @view.ask_for(:price).to_i
new_meal = Meal.new(name: name, price: price)
@meal_repo.add(new_meal)
end
end
class MealsView
def display(meals)
meals.each do |meal|
puts "#{meal.id} - #{meal.name} - #{meal.price}"
end
end
def ask_for(stuff)
puts "enter #{stuff} for new meal:"
print '> '
gets.chomp
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment