lib/couchrest/model/designs.rb in couchrest_model-2.0.0.beta2 vs lib/couchrest/model/designs.rb in couchrest_model-2.0.0

- old
+ new

@@ -20,22 +20,41 @@ extend ActiveSupport::Concern module ClassMethods - # Add views and other design document features - # to the current model. - def design(prefix = nil, &block) + # Define a Design Document associated with the current model. + # + # This class method supports several cool features that make it much + # easier to define design documents. + # + # Adding a prefix allows you to associate multiple design documents with the same + # model. This is useful if you'd like to split your designs into seperate + # use cases; one for regular search functions and a second for stats for example. + # + # # Create a design doc with id _design/Cats + # design do + # view :by_name + # end + # + # # Create a design doc with id _design/Cats_stats + # design :stats do + # view :by_age, :reduce => :stats + # end + # + # + def design(*args, &block) + opts = prepare_design_options(*args) # Store ourselves a copy of this design spec incase any other model inherits. - (@_design_blocks ||= [ ]) << {:args => [prefix], :block => block} + (@_design_blocks ||= [ ]) << {:args => args, :block => block} - mapper = DesignMapper.new(self, prefix) + mapper = DesignMapper.new(self, opts[:prefix]) mapper.instance_eval(&block) if block_given? # Create an 'all' view if no prefix and one has not been defined already - mapper.view(:all) if prefix.nil? and !mapper.design_doc.has_view?(:all) + mapper.view(:all) if opts[:prefix].nil? and !mapper.design_doc.has_view?(:all) end def inherited(model) super @@ -66,78 +85,26 @@ def design_docs @_design_docs ||= [] end - end + private - # Map method calls defined in a design block to actions - # in the Design Document. - class DesignMapper - - # Basic mapper attributes - attr_accessor :model, :method, :prefix - - # Temporary variable storing the design doc - attr_accessor :design_doc - - def initialize(model, prefix = nil) - self.model = model - self.prefix = prefix - self.method = Design.method_name(prefix) - - create_model_design_doc_reader - self.design_doc = model.send(method) || assign_model_design_doc + def prepare_design_options(*args) + options = {} + if !args.first.is_a?(Hash) + options[:prefix] = args.shift + end + options.merge(args.last) unless args.empty? + prepare_source_paths(options) + options end - def disable_auto_update - design_doc.auto_update = false + def prepare_source_paths(options) + end - def enable_auto_update - design_doc.auto_update = true - end - - # Add the specified view to the design doc the definition was made in - # and create quick access methods in the model. - def view(name, opts = {}) - design_doc.create_view(name, opts) - end - - # Really simple design function that allows a filter - # to be added. Filters are simple functions used when listening - # to the _changes feed. - # - # No methods are created here, the design is simply updated. - # See the CouchDB API for more information on how to use this. - def filter(name, function) - design_doc.create_filter(name, function) - end - - # Convenience wrapper to access model's type key option. - def model_type_key - model.model_type_key - end - - protected - - # Create accessor in model and assign a new design doc. - # New design doc is returned ready to use. - def create_model_design_doc_reader - model.instance_eval "def #{method}; @#{method}; end" - end - - def assign_model_design_doc - doc = Design.new(model, prefix) - model.instance_variable_set("@#{method}", doc) - model.design_docs << doc - - # Set defaults - doc.auto_update = model.auto_update_design_doc - - doc - end - end + end end end