Created
October 17, 2011 03:34
-
-
Save LRDesign/1291887 to your computer and use it in GitHub Desktop.
Revisions
-
Logical Reality Design created this gist
Oct 17, 2011 .There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,91 @@ require 'tsort' module Rails module Initializable def self.included(base) base.extend ClassMethods end class Initializer attr_reader :name, :block def initialize(name, context, options, &block) options[:group] ||= :default @name, @context, @options, @block = name, context, options, block end def before @options[:before] end def after @options[:after] end def belongs_to?(group) @options[:group] == group || @options[:group] == :all end def run(*args) @context.instance_exec(*args, &block) end def bind(context) return self if @context Initializer.new(@name, context, @options, &block) end end class Collection < Array include TSort alias :tsort_each_node :each def tsort_each_child(initializer, &block) select { |i| i.before == initializer.name || i.name == initializer.after }.each(&block) end def +(other) Collection.new(to_a + other.to_a) end end def run_initializers(group=:default, *args) return if instance_variable_defined?(:@ran) initializers.tsort.each do |initializer| pp "Running Initializer: #{initializer.try(:name)}" initializer.run(*args) if initializer.belongs_to?(group) end @ran = true end def initializers @initializers ||= self.class.initializers_for(self) end module ClassMethods def initializers @initializers ||= Collection.new end def initializers_chain initializers = Collection.new ancestors.reverse_each do |klass| next unless klass.respond_to?(:initializers) initializers = initializers + klass.initializers end initializers end def initializers_for(binding) Collection.new(initializers_chain.map { |i| i.bind(binding) }) end def initializer(name, opts = {}, &blk) raise ArgumentError, "A block must be passed when defining an initializer" unless blk opts[:after] ||= initializers.last.name unless initializers.empty? || initializers.find { |i| i.name == opts[:before] } initializers << Initializer.new(name, nil, opts, &blk) pp "INITIALIZERS" => initializers if name =~ /factory_girl/ end end end end