Skip to content

Instantly share code, notes, and snippets.

@localhostdotdev
Last active April 10, 2019 01:14
Show Gist options
  • Save localhostdotdev/25f1efc0c0eba0436e4bb5a632b59cdc to your computer and use it in GitHub Desktop.
Save localhostdotdev/25f1efc0c0eba0436e4bb5a632b59cdc to your computer and use it in GitHub Desktop.
preview of a simple factory thing for ruby which I use instead of factorybot / fixtures
class Factory
def self.create(clazz, *args)
build(clazz, *args).tap(&:save!)
end
def self.build(clazz, *args)
"Factory::#{clazz}".constantize.new(clazz, *args).tap(&:process).record
end
def self.create_list(clazz, count, *args)
(1..count).map { create(clazz, *args) }
end
def self.build_list(clazz, count, *args)
(1..count).map { build(clazz, *args) }
end
end
class Factory::Base
attr_reader :record
def initialize(clazz, *arguments)
@clazz = clazz
@arguments = arguments
@args = arguments.select { |arg| arg.is_a?(Hash) }
@args = @args.reduce({}, &:merge)
@traits = arguments.reject { |arg| arg.is_a?(Hash) }
@record = clazz.new
end
def args(key, default = nil, &block)
block ? @args.fetch(key, &block) : @args.fetch(key, default)
end
def default?
@traits.empty?
end
def trait?(trait)
@traits.include?(trait)
end
def create(clazz, *args)
Factory.create(clazz, *args)
end
def build(clazz, *args)
Factory.build(clazz, *args)
end
def save!(record)
record.tap(&:save).tap do |record|
raise "#{record}: #{record.error_messages}" if record.errors.any?
end
end
def name
Faker::Name.name
end
def password
rand(1e10).to_s(16)
end
end
class Factory::User < Factory::Base
def process
record.name = args(:name, name)
record.password = args(:password, password)
end
end
Factory.create(User)
Factory.build_list(User, 10)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment