Skip to content

Instantly share code, notes, and snippets.

@eterps
Created January 24, 2017 10:37
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 eterps/45985c48d6b1893a22e8e051c0a3c15f to your computer and use it in GitHub Desktop.
Save eterps/45985c48d6b1893a22e8e051c0a3c15f to your computer and use it in GitHub Desktop.
# Inverting Dependencies: Hexagonal Architecture
# A Blog post
class Post
def self.write_new_from(title, content)
new(title, content)
end
private
def initialize(title, content)
raise 'Title cannot be empty' if title.empty?
raise 'Content cannot be empty' if content.empty?
@title = title
@content = content
end
end
# A Blog post repository
module PostRepository
def by_id(_id)
raise NotImplementedError
end
def add(_post)
raise NotImplementedError
end
end
# A PDO post repository
class PDOPostRepository
include PostRepository
def initialize(db)
@db = db
end
def by_id(id)
@db[:posts][id: id]
end
def add(post)
@db.transaction do
@db[:posts].insert title: post.title, content: post.content
end
end
end
# Application layer
class PostService
def initialize(post_repository)
@post_repository = post_repository
end
def create_post(title, content) # =========================> This can be subdivided by adding use case classes per action (CreatePost, DeletePost etc.)
post = Post.write_new_from(title, content)
@post_repository.add post
post
end
end
# Posts controller
class PostsController
# :reek:TooManyStatements
def update(request) # rubocop:disable Metrics/MethodLength
db = PDO.new('mysql:host=localhost;dbname=my_database',
'a_username',
'4_p4ssw0rd',
init_command: 'SET NAMES utf8mb4')
# post_repository = PDOPostRepository.new(db)
# post_repository = PDOPostRepository.new(settings.db)
post_repository = PDOPostRepository.new(Registry.post_repository_db)
post_service = PostService.new(post_repository)
begin
post_service.create_post request['title'], request['content']
add_flash 'notice', 'Post has been created successfully!'
rescue
add_flash 'error', 'Unable to create the post!'
end
render 'posts/posts.rhtml'
end
end
# PostsController.new.update({'title' => 'foo', 'content' => 'bar'})
# Registry
module Registry
def self.post_repository_db
@post_repository_db ||= PDO.new(
'mysql:host=localhost;dbname=my_database',
'a_username',
'4_p4ssw0rd',
init_command: 'SET NAMES utf8mb4'
)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment