Skip to content

Instantly share code, notes, and snippets.

@pricees
Created September 24, 2013 21:52
Show Gist options
  • Select an option

  • Save pricees/6691820 to your computer and use it in GitHub Desktop.

Select an option

Save pricees/6691820 to your computer and use it in GitHub Desktop.
This is a module I wrote to help our move towards a Cockburn-esque Hexagonal Architecture in Rails
# This purpose of this module is to assist developers in moving towards a more
# hexagonal architecture
#
# Driver demo program for hexagonal helper
#
#
# require "./hexagonal_helper.rb"
#
# module Foo; end
# module Foo::Persistence; end
# class Foo::Base; end
#
# class Foo::Persistence::ActiveRecord
# def hello
# puts "This is ActiveRecord"
# end
# end
#
# class Foo::Persistence::Redis
# def hello
# puts "This is Redis"
# end
# end
#
# Foo::Base.send :include, HexagonalHelper
# Foo::Base.new("Foo::Persistence::Redis").hello
# Foo::Base.new("Foo::Persistence::ActiveRecord").hello
#
# OUTPUT
#
# => This is Redis
# => This is ActiveRecord
module HexagonalHelper
attr_reader :connection
class ConnectionError < StandardError; end
# Sets the connection
#
# connection_class - String containing full namespace of persistent layer
#
# Return instance of connection class
# Raises Runtime Error
def initialize(connection_class)
klass = connection_class.to_s.
split(/::/).
inject(Object) { |klass, ns| klass.const_get(ns) }
@connection = klass.new
rescue NameError
raise NameError, "No Persistence Adapter named '#{connection_class}'"
end
# Public: Build a delegate method on the EiginClass
#
# method - method name that connection responds to.
# Returns a proc
def build_it!(method)
block = lambda { |*args| connection.send(method, *args) }
self.class.send(:define_method, method, block)
end
# You love meta programming, I love meta programming, we all love meta
# programming
def method_missing(method, *args, &block)
@connection.respond_to?(method) || super
# If you got here, that connection responds!
build_it!(method)[*args]
end
end
@pricees

pricees commented Oct 11, 2013

Copy link
Copy Markdown
Author

The runner:

require "./hexagonal_helper.rb"

module Foo; end
class Foo::Base; end
module Foo::Persistence; end

class Foo::Persistence::ActiveRecord
  def hello
    "This is ActiveRecord"
  end
end

class Foo::Persistence::Redis
  def hello
    "This is Redis"
  end
end

Foo::Base.send :include, HexagonalHelper

p Foo::Base.new("Foo::Persistence::Redis").hello
p Foo::Base.new("Foo::Persistence::ActiveRecord").hello

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