Skip to content

Instantly share code, notes, and snippets.

@ArturT
Created September 23, 2015 17:38
Show Gist options
  • Save ArturT/a119b72c16151e1651c6 to your computer and use it in GitHub Desktop.
Save ArturT/a119b72c16151e1651c6 to your computer and use it in GitHub Desktop.
Entity and Repository
EntityVirtus = Virtus.model
ValueObjectVirtus = Virtus.value_object
class UUID < Virtus::Attribute
class String < ::String
end
def coerce(value)
value.present? ? String.new(value) : nil
end
end
class ProjectEntity < Entity
attribute :id, Integer
attribute :name, String
set_foreign_keys({
organization_id: Integer
})
set_referenced_attrs({
test_suites: Array[TestSuiteEntity]
})
end
class TestSuiteEntity < Entity
attribute :id, Integer
attribute :name, String
attribute :token, String
set_foreign_keys({
project_id: Integer
})
end
class TestSuiteRepository < BaseRepository
def initialize(entity_class = TestSuiteEntity, model_class = TestSuite)
super
end
def find_by_token(token)
record = model_class.find_by(token: token)
return unless record
entity_class.new(record.attributes)
end
end
class BaseRepository
def initialize(entity_class = nil, model_class = nil)
@entity_class = entity_class
@model_class = model_class
end
def save(entity)
if entity.id
record = model_class.find_by(id: entity.id)
record.update(entity.not_referenced_attrs)
else
record = model_class.create(entity.not_referenced_attrs)
end
entity_class.new(record.attributes)
end
private
def entity_class
@entity_class || raise(NotImplementedError)
end
def model_class
@model_class || raise(NotImplementedError)
end
end
class Entity
include EntityVirtus
class << self
def set_attrs(attrs={})
attrs.each do |attr, type|
attribute attr, type
end
end
alias_method :set_foreign_keys, :set_attrs
def set_referenced_attrs(attrs={})
@referenced_attrs = attrs.keys
set_attrs(attrs)
end
def referenced_attrs
@referenced_attrs || []
end
def set_timestamps
set_attrs({
updated_at: DateTime,
created_at: DateTime
})
end
end
def not_referenced_attrs
attributes.except(*self.class.referenced_attrs)
end
end
@ArturT
Copy link
Author

ArturT commented Sep 23, 2015

I don't use repository to initialize new Entity. Entity can be created outside of the repository. I use repository to store Entity in DB. I can ask repository to get entity so the repository handles database query and returns Entity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment