Permalink
Browse files

Extract complicated runner code into private class

Factory#run was getting confusing - it added callbacks to the proxy,
iterated over all attributes and operated on the proxy depending on if
there were overridtes, mutated the overrides hash, and then operated on
the mutated hash afterwards. This logic has been extracted into a
private Factory::Runner class. The goal is to make it easier to
understand everything that's occurring in order to instantiate and build
the class.
  • Loading branch information...
joshuaclayton committed Oct 20, 2011
1 parent e1ece10 commit 105d972aa899f50015e7261c76d64009e1da6a44
Showing with 78 additions and 22 deletions.
  1. +78 −22 lib/factory_girl/factory.rb
View
@@ -46,28 +46,16 @@ def define_trait(trait)
def run(proxy_class, overrides, &block) #:nodoc:
ensure_compiled
- proxy = proxy_class.new(build_class)
- callbacks.each { |callback| proxy.add_callback(callback) }
- overrides = overrides.symbolize_keys
-
- attributes.each do |attribute|
- factory_overrides = overrides.select { |attr, val| attribute.aliases_for?(attr) }
- if factory_overrides.empty?
- attribute.add_to(proxy)
- else
- factory_overrides.each do |attr, val|
- if attribute.ignored
- proxy.set_ignored(attr, val)
- else
- proxy.set(attr, val)
- end
-
- overrides.delete(attr)
- end
- end
- end
- overrides.each { |attr, val| proxy.set(attr, val) }
- result = proxy.result(@to_create_block)
+
+ runner_options = {
+ :attributes => attributes,
+ :callbacks => callbacks,
+ :to_create => @to_create_block,
+ :build_class => build_class,
+ :proxy_class => proxy_class
+ }
+
+ result = Runner.new(runner_options).run(overrides)
block ? block.call(result) : result
end
@@ -200,5 +188,73 @@ def parent
return unless @parent
FactoryGirl.factory_by_name(@parent)
end
+
+ class Runner
+ def initialize(options = {})
+ @attributes = options[:attributes]
+ @callbacks = options[:callbacks]
+ @to_create = options[:to_create]
+ @build_class = options[:build_class]
+ @proxy_class = options[:proxy_class]
+
+ @overrides = {}
+ end
+
+ def run(overrides = {})
+ @overrides = overrides.symbolize_keys
+
+ apply_callbacks
+ apply_attributes
+ apply_remaining_attributes
+
+ proxy.result(@to_create)
+ end
+
+ private
+
+ def apply_callbacks
+ @callbacks.each do |callback|
+ proxy.add_callback(callback)
+ end
+ end
+
+ def apply_attributes
+ @attributes.each do |attribute|
+ if overrides_for_attribute(attribute).any?
+ handle_overrides(attribute)
+ else
+ handle_attribute_without_overrides(attribute)
+ end
+ end
+ end
+
+ def overrides_for_attribute(attribute)
+ @overrides.select { |attr, val| attribute.aliases_for?(attr) }
+ end
+
+ def handle_overrides(attribute)
+ overrides_for_attribute(attribute).each do |attr, val|
+ if attribute.ignored
+ proxy.set_ignored(attr, val)
+ else
+ proxy.set(attr, val)
+ end
+
+ @overrides.delete(attr)
+ end
+ end
+
+ def handle_attribute_without_overrides(attribute)
+ attribute.add_to(proxy)
+ end
+
+ def apply_remaining_attributes
+ @overrides.each { |attr, val| proxy.set(attr, val) }
+ end
+
+ def proxy
+ @proxy ||= @proxy_class.new(@build_class)
+ end
+ end
end
end

0 comments on commit 105d972

Please sign in to comment.