Last active
December 25, 2015 17:39
-
-
Save cupakromer/7015104 to your computer and use it in GitHub Desktop.
MetaProgram some factories
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module ModelFactory | |
def self.factory(resource, defaults = {}) | |
resource = resource.downcase | |
defaults = defaults.dup.freeze | |
resource_defaults = "default_#{resource}_attributes".to_sym | |
build_resource = "build_#{resource}".to_sym | |
create_resource = "create_#{resource}".to_sym | |
define_method resource_defaults do | |
defaults | |
end | |
module_function resource_defaults | |
define_method build_resource do |opts = {}| | |
opts = send(resource_defaults).merge(opts).reject{ |o| :optional == o } | |
opts.each{ |k, v| opts[k] = v.call if v.is_a? Proc } | |
klass = self.class.const_get(resource.to_s.classify) | |
klass.new(opts) | |
end | |
module_function build_resource | |
define_method create_resource do |opts = {}| | |
send(build_resource, opts).tap{ |r| r.save! } | |
end | |
module_function create_resource | |
end | |
factory :ewok | |
factory :wampa, { size: :small, fur: :brown } | |
factory :jedi, lightsaber: :green, delusion_of_grandeur: :optional | |
factory :rebel, { alliance: true, joined_at: ->{ 1.week.ago } } | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module ModelFactory | |
FactoryNotFound = Class.new(RuntimeError) | |
def self.factories | |
@factories ||= {} | |
end | |
def self.factory(resource, defaults = {}) | |
factories[resource] = defaults.dup.freeze | |
end | |
module_function | |
def factory_defaults(resource) | |
factories.fetch(resource) { raise FactoryNotFound, resource } | |
end | |
def build(resource, opts = {}) | |
opts = factory_defaults(resource).merge(opts).reject{ |o| :optional == o } | |
opts.each{ |k, v| opts[k] = v.call if v.is_a? Proc } | |
resource.new(opts) | |
end | |
def create(resource, opts = {}) | |
build(resource, opts).tap{ |r| r.save! } | |
end | |
end | |
module ModelFactory | |
factory Ewok | |
factory Wampa, { size: :small, fur: :brown } | |
factory Jedi, lightsaber: :green, delusion_of_grandeur: :optional | |
factory Rebel, { alliance: true, joined_at: ->{ 1.week.ago } } | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment