def method_missing(method_id, *args)
      super if method_id == :to_ary

      if args.empty?
        Nodes::Stub.new method_id
      elsif (args.size == 1) && (Class === args[0])
        Nodes::Join.new(method_id, InnerJoin, args[0])
      else
        Nodes::Function.new method_id, args
      end
    end
def method_missing(method_id, *args)
      super if method_id == :to_ary

      if args.empty?
        Nodes::Stub.new method_id
      elsif (args.size == 1) && (Class === args[0])
        Nodes::Join.new(method_id, InnerJoin, args[0])
      else
        Nodes::Function.new method_id, args
      end
    end
Node generation inside DSL blocks.

 @overload node_name
   Creates a Stub. Method calls chained from this Stub will determine
   what type of node we eventually end up with.
   @return [Nodes::Stub] A stub with the name of the method
 @overload node_name(klass)
   Creates a Join with a polymorphic class matching the given parameter
   @param [Class] klass The polymorphic class of the join node
   @return [Nodes::Join] A join node with the name of the method and the given class
 @overload node_name(first_arg, *other_args)
   Creates a Function with the given arguments becoming the function's arguments
   @param first_arg The first argument
   @param *other_args Optional additional arguments
   @return [Nodes::Function] A function node for the given method name with the given arguments