Permalink
Browse files

Working on refactor so that design docs can be name spaced and old vi…

…ew code is no longer around
  • Loading branch information...
1 parent 0aef9df commit 5cf9d2e092ea83bd47273a283179326e3f595f74 @samlown samlown committed Jun 4, 2012
@@ -8,12 +8,9 @@ class Base < CouchRest::Document
include CouchRest::Model::Connection
include CouchRest::Model::Persistence
include CouchRest::Model::DocumentQueries
- include CouchRest::Model::Views
- include CouchRest::Model::DesignDoc
include CouchRest::Model::ExtendedAttachments
include CouchRest::Model::ClassProxy
include CouchRest::Model::Proxyable
- include CouchRest::Model::Collection
include CouchRest::Model::PropertyProtection
include CouchRest::Model::Associations
include CouchRest::Model::Validations
@@ -66,36 +63,6 @@ def initialize(attributes = {}, options = {})
run_callbacks(:initialize) { self }
end
-
- # Temp solution to make the view_by methods available
- def self.method_missing(m, *args, &block)
- if has_view?(m)
- query = args.shift || {}
- return view(m, query, *args, &block)
- elsif m.to_s =~ /^find_(by_.+)/
- view_name = $1
- if has_view?(view_name)
- return first_from_view(view_name, *args)
- end
- end
- super
- end
-
- # compatbility for 1.8, it does not use respond_to_missing?
- # thing is, when using it like this only, doing method(:find_by_view)
- # will throw an error
- def self.respond_to?(m, include_private = false)
- super || respond_to_missing?(m, include_private)
- end
-
- # ruby 1.9 feature
- # this allows ruby to know that the method is defined using
- # method_missing, and as such, method(:find_by_view) will actually
- # give a Method back, and not throw an error like in 1.8!
- def self.respond_to_missing?(m, include_private = false)
- has_view?(m) || has_view?(m.to_s[/^find_(by_.+)/, 1])
- end
-
def to_key
new? ? nil : [id]
end
@@ -1,273 +0,0 @@
-module CouchRest
- module Model
- # Warning! The Collection module is seriously depricated.
- # Use the new Design Views instead, as this code copies many other parts
- # of CouchRest Model.
- #
- # Expect this to be removed soon.
- #
- module Collection
-
- def self.included(base)
- base.extend(ClassMethods)
- end
-
- module ClassMethods
-
- # Creates a new class method, find_all_<collection_name>, that will
- # execute the view specified with the design_doc and view_name
- # parameters, along with the specified view_options. This method will
- # return the results of the view as an Array of objects which are
- # instances of the class.
- #
- # This method is handy for objects that do not use the view_by method
- # to declare their views.
- def provides_collection(collection_name, design_doc, view_name, view_options)
- class_eval <<-END, __FILE__, __LINE__ + 1
- def self.find_all_#{collection_name}(options = {})
- view_options = #{view_options.inspect} || {}
- CollectionProxy.new(options[:database] || database, "#{design_doc}", "#{view_name}", view_options.merge(options), Kernel.const_get('#{self}'))
- end
- END
- end
-
- # Fetch a group of objects from CouchDB. Options can include:
- # :page - Specifies the page to load (starting at 1)
- # :per_page - Specifies the number of objects to load per page
- #
- # Defaults are used if these options are not specified.
- def paginate(options)
- proxy = create_collection_proxy(options)
- proxy.paginate(options)
- end
-
- # Iterate over the objects in a collection, fetching them from CouchDB
- # in groups. Options can include:
- # :page - Specifies the page to load
- # :per_page - Specifies the number of objects to load per page
- #
- # Defaults are used if these options are not specified.
- def paginated_each(options, &block)
- search = options.delete(:search)
- unless search == true
- proxy = create_collection_proxy(options)
- else
- proxy = create_search_collection_proxy(options)
- end
- proxy.paginated_each(options, &block)
- end
-
- # Create a CollectionProxy for the specified view and options.
- # CollectionProxy behaves just like an Array, but offers support for
- # pagination.
- def collection_proxy_for(design_doc, view_name, view_options = {})
- options = view_options.merge(:design_doc => design_doc, :view_name => view_name)
- create_collection_proxy(options)
- end
-
- private
-
- def create_collection_proxy(options)
- design_doc, view_name, view_options = parse_view_options(options)
- CollectionProxy.new(options[:database] || database, design_doc, view_name, view_options, self)
- end
-
- def create_search_collection_proxy(options)
- design_doc, search_name, search_options = parse_search_options(options)
- CollectionProxy.new(options[:database] || database, design_doc, search_name, search_options, self, :search)
- end
-
- def parse_view_options(options)
- design_doc = options.delete(:design_doc)
- raise ArgumentError, 'design_doc is required' if design_doc.nil?
-
- view_name = options.delete(:view_name)
- raise ArgumentError, 'view_name is required' if view_name.nil?
-
- default_view_options = (design_doc.class == Design &&
- design_doc['views'][view_name.to_s] &&
- design_doc['views'][view_name.to_s]["couchrest-defaults"]) || {}
- view_options = default_view_options.merge(options)
- view_options.delete(:database)
-
- [design_doc, view_name, view_options]
- end
-
- def parse_search_options(options)
- design_doc = options.delete(:design_doc)
- raise ArgumentError, 'design_doc is required' if design_doc.nil?
-
- search_name = options.delete(:view_name)
- raise ArgumentError, 'search_name is required' if search_name.nil?
-
- search_options = options.clone
- search_options.delete(:database)
-
- [design_doc, search_name, search_options]
- end
-
- end
-
- class CollectionProxy
- alias_method :proxy_respond_to?, :respond_to?
- instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|proxy_|^object_id$)/ }
-
- DEFAULT_PAGE = 1
- DEFAULT_PER_PAGE = 30
-
- # Create a new CollectionProxy to represent the specified view. If a
- # container class is specified, the proxy will create an object of the
- # given type for each row that comes back from the view. If no
- # container class is specified, the raw results are returned.
- #
- # The CollectionProxy provides support for paginating over a collection
- # via the paginate, and paginated_each methods.
- def initialize(database, design_doc, view_name, view_options = {}, container_class = nil, query_type = :view)
- raise ArgumentError, "database is a required parameter" if database.nil?
-
- @database = database
- @container_class = container_class
- @query_type = query_type
-
- strip_pagination_options(view_options)
- @view_options = view_options
-
- if design_doc.class == Design
- @view_name = "#{design_doc.name}/#{view_name}"
- else
- @view_name = "#{design_doc}/#{view_name}"
- end
-
- # Save the design doc, ready for use
- @container_class.save_design_doc(@database)
- end
-
- # See Collection.paginate
- def paginate(options = {})
- page, per_page = parse_options(options)
- results = @database.send(@query_type, @view_name, pagination_options(page, per_page))
- remember_where_we_left_off(results, page)
- instances = convert_to_container_array(results)
-
- begin
- if Kernel.const_get('WillPaginate')
- total_rows = results['total_rows'].to_i
- paginated = WillPaginate::Collection.create(page, per_page, total_rows) do |pager|
- pager.replace(instances)
- end
- return paginated
- end
- rescue NameError
- # When not using will_paginate, not much we could do about this. :x
- end
- return instances
- end
-
- # See Collection.paginated_each
- def paginated_each(options = {}, &block)
- page, per_page = parse_options(options)
-
- begin
- collection = paginate({:page => page, :per_page => per_page})
- collection.each(&block)
- page += 1
- end until collection.size < per_page
- end
-
- def respond_to?(*args)
- proxy_respond_to?(*args) || (load_target && @target.respond_to?(*args))
- end
-
- # Explicitly proxy === because the instance method removal above
- # doesn't catch it.
- def ===(other)
- load_target
- other === @target
- end
-
- private
-
- def method_missing(method, *args)
- if load_target
- if block_given?
- @target.send(method, *args) { |*block_args| yield(*block_args) }
- else
- @target.send(method, *args)
- end
- end
- end
-
- def load_target
- unless loaded?
- @view_options.merge!({:include_docs => true}) if @query_type == :search
- results = @database.send(@query_type, @view_name, @view_options)
- @target = convert_to_container_array(results)
- end
- @loaded = true
- @target
- end
-
- def loaded?
- @loaded
- end
-
- def reload
- reset
- load_target
- self unless @target.nil?
- end
-
- def reset
- @loaded = false
- @target = nil
- end
-
- def inspect
- load_target
- @target.inspect
- end
-
- def convert_to_container_array(results)
- if @container_class.nil?
- results
- else
- results['rows'].collect { |row| @container_class.build_from_database(row['doc']) } unless results['rows'].nil?
- end
- end
-
- def pagination_options(page, per_page)
- view_options = @view_options.clone
- if @query_type == :view && @last_key && @last_docid && @last_page == page - 1
- key = view_options.delete(:key)
- end_key = view_options[:endkey] || key
- options = { :startkey => @last_key, :endkey => end_key, :startkey_docid => @last_docid, :limit => per_page, :skip => 1 }
- else
- options = { :limit => per_page, :skip => per_page * (page - 1) }
- end
- options[:include_docs] = true
- view_options.merge(options)
- end
-
- def parse_options(options)
- page = options.delete(:page) || DEFAULT_PAGE
- per_page = options.delete(:per_page) || DEFAULT_PER_PAGE
- [page.to_i, per_page.to_i]
- end
-
- def strip_pagination_options(options)
- parse_options(options)
- end
-
- def remember_where_we_left_off(results, page)
- last_row = results['rows'].last
- if last_row
- @last_key = last_row['key']
- @last_docid = last_row['id']
- end
- @last_page = page
- end
- end
-
- end
- end
-end
Oops, something went wrong.

0 comments on commit 5cf9d2e

Please sign in to comment.