require "polo/version" require "polo/collector" require "polo/translator" require "polo/configuration" module Polo # Public: Traverses a dependency graph based on a seed ActiveRecord object # and generates all the necessary INSERT queries for each one of the records # it finds along the way. # # base_class - An ActiveRecord::Base class for the seed record. # id - An ID used to find the desired seed record. # # dependency_tree - An ActiveRecord::Associations::Preloader compliant that # will define the path Polo will traverse. # # (from ActiveRecord::Associations::Preloader docs) # It may be: # - a Symbol or a String which specifies a single association name. For # example, specifying +:books+ allows this method to preload all books # for an Author. # - an Array which specifies multiple association names. This array # is processed recursively. For example, specifying <tt>[:avatar, :books]</tt> # allows this method to preload an author's avatar as well as all of his # books. # - a Hash which specifies multiple association names, as well as # association names for the to-be-preloaded association objects. For # example, specifying <tt>{ author: :avatar }</tt> will preload a # book's author, as well as that author's avatar. # # +:associations+ has the same format as the +:include+ option for # <tt>ActiveRecord::Base.find</tt>. So +associations+ could look like this: # # :books # [ :books, :author ] # { author: :avatar } # [ :books, { author: :avatar } ] # def self.explore(base_class, id, dependencies={}) Traveler.collect(base_class, id, dependencies).translate(defaults) end # Public: Sets up global settings for Polo # # block - Takes a block with the settings you decide to use # # obfuscate - Takes a blacklist with sensitive fields you wish to scramble # on_duplicate - Defines the on_duplicate strategy for your INSERTS # e.g. :override, :ignore # # usage: # Polo.configure do # obfuscate(:email, :password, :credit_card) # on_duplicate(:override) # end # def self.configure(&block) @configuration = Configuration.new @configuration.instance_eval(&block) if block_given? @configuration end # Public: Returns the default settings # def self.defaults @configuration || configure end class Traveler def self.collect(base_class, id, dependencies={}) selects = Collector.new(base_class, id, dependencies).collect new(selects) end def initialize(selects) @selects = selects end def translate(configuration=Configuration.new) Translator.new(@selects, configuration).translate end end end