couchrest_model 1.0.0 → 1.1.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -1
- data/Gemfile.lock +19 -20
- data/README.md +145 -20
- data/VERSION +1 -1
- data/couchrest_model.gemspec +2 -3
- data/history.txt +14 -0
- data/lib/couchrest/model/associations.rb +4 -4
- data/lib/couchrest/model/base.rb +5 -0
- data/lib/couchrest/model/callbacks.rb +1 -2
- data/lib/couchrest/model/collection.rb +1 -1
- data/lib/couchrest/model/designs/view.rb +486 -0
- data/lib/couchrest/model/designs.rb +81 -0
- data/lib/couchrest/model/document_queries.rb +1 -1
- data/lib/couchrest/model/persistence.rb +25 -16
- data/lib/couchrest/model/properties.rb +5 -1
- data/lib/couchrest/model/property.rb +2 -2
- data/lib/couchrest/model/proxyable.rb +152 -0
- data/lib/couchrest/model/typecast.rb +1 -1
- data/lib/couchrest/model/validations/casted_model.rb +3 -1
- data/lib/couchrest/model/validations/locale/en.yml +1 -1
- data/lib/couchrest/model/validations/uniqueness.rb +6 -7
- data/lib/couchrest/model/validations.rb +1 -0
- data/lib/couchrest/model/views.rb +11 -9
- data/lib/couchrest_model.rb +3 -0
- data/spec/couchrest/assocations_spec.rb +2 -2
- data/spec/couchrest/base_spec.rb +15 -1
- data/spec/couchrest/casted_model_spec.rb +30 -12
- data/spec/couchrest/class_proxy_spec.rb +2 -2
- data/spec/couchrest/collection_spec.rb +89 -0
- data/spec/couchrest/designs/view_spec.rb +766 -0
- data/spec/couchrest/designs_spec.rb +110 -0
- data/spec/couchrest/persistence_spec.rb +36 -7
- data/spec/couchrest/property_spec.rb +15 -0
- data/spec/couchrest/proxyable_spec.rb +329 -0
- data/spec/couchrest/{validations.rb → validations_spec.rb} +1 -3
- data/spec/couchrest/view_spec.rb +19 -91
- data/spec/fixtures/base.rb +8 -6
- data/spec/fixtures/more/article.rb +1 -1
- data/spec/fixtures/more/course.rb +4 -2
- metadata +21 -76
- data/lib/couchrest/model/view.rb +0 -190
@@ -58,8 +58,8 @@ module CouchRest::Model
|
|
58
58
|
if default.class == Proc
|
59
59
|
default.call
|
60
60
|
else
|
61
|
-
#
|
62
|
-
default
|
61
|
+
# TODO identify cause of mutex errors
|
62
|
+
Marshal.load(Marshal.dump(default))
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
@@ -0,0 +1,152 @@
|
|
1
|
+
module CouchRest
|
2
|
+
module Model
|
3
|
+
# :nodoc: Because I like inventing words
|
4
|
+
module Proxyable
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
attr_accessor :model_proxy
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
|
13
|
+
# Define a collection that will use the base model for the database connection
|
14
|
+
# details.
|
15
|
+
def proxy_for(model_name, options = {})
|
16
|
+
db_method = options[:database_method] || "proxy_database"
|
17
|
+
options[:class_name] ||= model_name.to_s.singularize.camelize
|
18
|
+
class_eval <<-EOS, __FILE__, __LINE__ + 1
|
19
|
+
def #{model_name}
|
20
|
+
unless respond_to?('#{db_method}')
|
21
|
+
raise "Missing ##{db_method} method for proxy"
|
22
|
+
end
|
23
|
+
@#{model_name} ||= CouchRest::Model::Proxyable::ModelProxy.new(::#{options[:class_name]}, self, self.class.to_s.underscore, #{db_method})
|
24
|
+
end
|
25
|
+
EOS
|
26
|
+
end
|
27
|
+
|
28
|
+
def proxied_by(model_name, options = {})
|
29
|
+
raise "Model can only be proxied once or ##{model_name} already defined" if method_defined?(model_name)
|
30
|
+
attr_accessor model_name
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class ModelProxy
|
35
|
+
|
36
|
+
attr_reader :model, :owner, :owner_name, :database
|
37
|
+
|
38
|
+
def initialize(model, owner, owner_name, database)
|
39
|
+
@model = model
|
40
|
+
@owner = owner
|
41
|
+
@owner_name = owner_name
|
42
|
+
@database = database
|
43
|
+
end
|
44
|
+
|
45
|
+
# Base
|
46
|
+
|
47
|
+
def new(*args)
|
48
|
+
proxy_update(model.new(*args))
|
49
|
+
end
|
50
|
+
|
51
|
+
def build_from_database(doc = {})
|
52
|
+
proxy_update(model.build_from_database(doc))
|
53
|
+
end
|
54
|
+
|
55
|
+
def method_missing(m, *args, &block)
|
56
|
+
if has_view?(m)
|
57
|
+
if model.respond_to?(m)
|
58
|
+
return model.send(m, *args).proxy(self)
|
59
|
+
else
|
60
|
+
query = args.shift || {}
|
61
|
+
return view(m, query, *args, &block)
|
62
|
+
end
|
63
|
+
elsif m.to_s =~ /^find_(by_.+)/
|
64
|
+
view_name = $1
|
65
|
+
if has_view?(view_name)
|
66
|
+
return first_from_view(view_name, *args)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
super
|
70
|
+
end
|
71
|
+
|
72
|
+
# DocumentQueries
|
73
|
+
|
74
|
+
def all(opts = {}, &block)
|
75
|
+
proxy_update_all(@model.all({:database => @database}.merge(opts), &block))
|
76
|
+
end
|
77
|
+
|
78
|
+
def count(opts = {})
|
79
|
+
@model.count({:database => @database}.merge(opts))
|
80
|
+
end
|
81
|
+
|
82
|
+
def first(opts = {})
|
83
|
+
proxy_update(@model.first({:database => @database}.merge(opts)))
|
84
|
+
end
|
85
|
+
|
86
|
+
def last(opts = {})
|
87
|
+
proxy_update(@model.last({:database => @database}.merge(opts)))
|
88
|
+
end
|
89
|
+
|
90
|
+
def get(id)
|
91
|
+
proxy_update(@model.get(id, @database))
|
92
|
+
end
|
93
|
+
alias :find :get
|
94
|
+
|
95
|
+
# Views
|
96
|
+
|
97
|
+
def has_view?(view)
|
98
|
+
@model.has_view?(view)
|
99
|
+
end
|
100
|
+
|
101
|
+
def view_by(*args)
|
102
|
+
@model.view_by(*args)
|
103
|
+
end
|
104
|
+
|
105
|
+
def view(name, query={}, &block)
|
106
|
+
proxy_update_all(@model.view(name, {:database => @database}.merge(query), &block))
|
107
|
+
end
|
108
|
+
|
109
|
+
def first_from_view(name, *args)
|
110
|
+
# add to first hash available, or add to end
|
111
|
+
(args.last.is_a?(Hash) ? args.last : (args << {}).last)[:database] = @database
|
112
|
+
proxy_update(@model.first_from_view(name, *args))
|
113
|
+
end
|
114
|
+
|
115
|
+
# DesignDoc
|
116
|
+
|
117
|
+
def design_doc
|
118
|
+
@model.design_doc
|
119
|
+
end
|
120
|
+
|
121
|
+
def refresh_design_doc(db = nil)
|
122
|
+
@model.refresh_design_doc(db || @database)
|
123
|
+
end
|
124
|
+
|
125
|
+
def save_design_doc(db = nil)
|
126
|
+
@model.save_design_doc(db || @database)
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
protected
|
131
|
+
|
132
|
+
# Update the document's proxy details, specifically, the fields that
|
133
|
+
# link back to the original document.
|
134
|
+
def proxy_update(doc)
|
135
|
+
if doc
|
136
|
+
doc.database = @database if doc.respond_to?(:database=)
|
137
|
+
doc.model_proxy = self if doc.respond_to?(:model_proxy=)
|
138
|
+
doc.send("#{owner_name}=", owner) if doc.respond_to?("#{owner_name}=")
|
139
|
+
end
|
140
|
+
doc
|
141
|
+
end
|
142
|
+
|
143
|
+
def proxy_update_all(docs)
|
144
|
+
docs.each do |doc|
|
145
|
+
proxy_update(doc)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
@@ -79,7 +79,7 @@ module CouchRest
|
|
79
79
|
# Match numeric string
|
80
80
|
def typecast_to_numeric(value, method)
|
81
81
|
if value.respond_to?(:to_str)
|
82
|
-
if value.gsub(/,/, '.').gsub(/\.(?!\d*\Z)/, '').to_str =~ /\A(-?(?:0|[1-9]\d*)(?:\.\d+)?|(?:\.\d+))\z/
|
82
|
+
if value.strip.gsub(/,/, '.').gsub(/\.(?!\d*\Z)/, '').to_str =~ /\A(-?(?:0|[1-9]\d*)(?:\.\d+)?|(?:\.\d+))\z/
|
83
83
|
$1.send(method)
|
84
84
|
else
|
85
85
|
value
|
@@ -6,7 +6,9 @@ module CouchRest
|
|
6
6
|
def validate_each(document, attribute, value)
|
7
7
|
values = value.is_a?(Array) ? value : [value]
|
8
8
|
return if values.collect {|doc| doc.nil? || doc.valid? }.all?
|
9
|
-
|
9
|
+
error_options = { :value => value }
|
10
|
+
error_options[:message] = options[:message] if options[:message]
|
11
|
+
document.errors.add(attribute, :invalid, error_options)
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
@@ -9,19 +9,19 @@ module CouchRest
|
|
9
9
|
|
10
10
|
# Ensure we have a class available so we can check for a usable view
|
11
11
|
# or add one if necessary.
|
12
|
-
def setup(
|
13
|
-
@
|
12
|
+
def setup(model)
|
13
|
+
@model = model
|
14
14
|
end
|
15
15
|
|
16
|
-
|
17
16
|
def validate_each(document, attribute, value)
|
18
17
|
view_name = options[:view].nil? ? "by_#{attribute}" : options[:view]
|
18
|
+
model = document.model_proxy || @model
|
19
19
|
# Determine the base of the search
|
20
|
-
base = options[:proxy].nil? ?
|
20
|
+
base = options[:proxy].nil? ? model : document.instance_eval(options[:proxy])
|
21
21
|
|
22
22
|
if base.respond_to?(:has_view?) && !base.has_view?(view_name)
|
23
23
|
raise "View #{document.class.name}.#{options[:view]} does not exist!" unless options[:view].nil?
|
24
|
-
|
24
|
+
model.view_by attribute
|
25
25
|
end
|
26
26
|
|
27
27
|
docs = base.view(view_name, :key => value, :limit => 2, :include_docs => false)['rows']
|
@@ -32,11 +32,10 @@ module CouchRest
|
|
32
32
|
end
|
33
33
|
|
34
34
|
if docs.length > 0
|
35
|
-
document.errors.add(attribute, :taken,
|
35
|
+
document.errors.add(attribute, :taken, options.merge(:value => value))
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
|
40
39
|
end
|
41
40
|
|
42
41
|
end
|
@@ -85,9 +85,14 @@ module CouchRest
|
|
85
85
|
end
|
86
86
|
|
87
87
|
# returns stored defaults if there is a view named this in the design doc
|
88
|
-
def has_view?(
|
89
|
-
|
90
|
-
|
88
|
+
def has_view?(name)
|
89
|
+
design_doc && design_doc.has_view?(name)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Check if the view can be reduced by checking to see if it has a
|
93
|
+
# reduce function.
|
94
|
+
def can_reduce_view?(name)
|
95
|
+
design_doc && design_doc.can_reduce_view?(name)
|
91
96
|
end
|
92
97
|
|
93
98
|
# Dispatches to any named view.
|
@@ -127,12 +132,9 @@ module CouchRest
|
|
127
132
|
if raw || (opts.has_key?(:include_docs) && opts[:include_docs] == false)
|
128
133
|
fetch_view(db, name, opts, &block)
|
129
134
|
else
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
view = fetch_view db, name, opts.merge({:include_docs => true}), &block
|
134
|
-
view['rows'].collect{|r|create_from_database(r['doc'])} if view['rows']
|
135
|
-
end
|
135
|
+
opts = opts.merge(:include_docs => true)
|
136
|
+
view = fetch_view db, name, opts, &block
|
137
|
+
view['rows'].collect{|r| build_from_database(r['doc'])} if view['rows']
|
136
138
|
end
|
137
139
|
end
|
138
140
|
|
data/lib/couchrest_model.rb
CHANGED
@@ -37,9 +37,12 @@ require "couchrest/model/views"
|
|
37
37
|
require "couchrest/model/design_doc"
|
38
38
|
require "couchrest/model/extended_attachments"
|
39
39
|
require "couchrest/model/class_proxy"
|
40
|
+
require "couchrest/model/proxyable"
|
40
41
|
require "couchrest/model/collection"
|
41
42
|
require "couchrest/model/associations"
|
42
43
|
require "couchrest/model/configuration"
|
44
|
+
require "couchrest/model/designs"
|
45
|
+
require "couchrest/model/designs/view"
|
43
46
|
|
44
47
|
# Monkey patches applied to couchrest
|
45
48
|
require "couchrest/model/support/couchrest"
|
@@ -44,11 +44,11 @@ describe "Assocations" do
|
|
44
44
|
end
|
45
45
|
|
46
46
|
it "should raise error if class name does not exist" do
|
47
|
-
lambda
|
47
|
+
lambda do
|
48
48
|
class TestBadAssoc < CouchRest::Model::Base
|
49
49
|
belongs_to :test_bad_item
|
50
50
|
end
|
51
|
-
|
51
|
+
end.should raise_error(NameError, /TestBadAssoc#test_bad_item/)
|
52
52
|
end
|
53
53
|
|
54
54
|
it "should allow override of foreign key" do
|
data/spec/couchrest/base_spec.rb
CHANGED
@@ -34,10 +34,16 @@ describe "Model Base" do
|
|
34
34
|
@obj.should be_new_record
|
35
35
|
end
|
36
36
|
|
37
|
-
it "should not
|
37
|
+
it "should not fail with nil argument" do
|
38
38
|
@obj = Basic.new(nil)
|
39
39
|
@obj.should_not be_nil
|
40
40
|
end
|
41
|
+
|
42
|
+
it "should allow the database to be set" do
|
43
|
+
@obj = Basic.new(nil, :database => 'database')
|
44
|
+
@obj.database.should eql('database')
|
45
|
+
end
|
46
|
+
|
41
47
|
end
|
42
48
|
|
43
49
|
describe "ActiveModel compatability Basic" do
|
@@ -184,6 +190,14 @@ describe "Model Base" do
|
|
184
190
|
obj = WithDefaultValues.new(:preset => 'test')
|
185
191
|
obj.preset = 'test'
|
186
192
|
end
|
193
|
+
|
194
|
+
it "should keep default values for new instances" do
|
195
|
+
obj = WithDefaultValues.new
|
196
|
+
obj.preset[:alpha] = 123
|
197
|
+
obj.preset.should == {:right => 10, :top_align => false, :alpha => 123}
|
198
|
+
another = WithDefaultValues.new
|
199
|
+
another.preset.should == {:right => 10, :top_align => false}
|
200
|
+
end
|
187
201
|
|
188
202
|
it "should work with a default empty array" do
|
189
203
|
obj = WithDefaultValues.new(:tags => ['spec'])
|
@@ -24,19 +24,24 @@ class DummyModel < CouchRest::Model::Base
|
|
24
24
|
property :sub_models do |child|
|
25
25
|
child.property :title
|
26
26
|
end
|
27
|
+
property :param_free_sub_models do
|
28
|
+
property :title
|
29
|
+
end
|
27
30
|
end
|
28
31
|
|
29
32
|
class WithCastedCallBackModel < Hash
|
30
33
|
include CouchRest::Model::CastedModel
|
31
34
|
property :name
|
32
|
-
property :
|
33
|
-
property :
|
35
|
+
property :run_before_validation
|
36
|
+
property :run_after_validation
|
37
|
+
|
38
|
+
validates_presence_of :run_before_validation
|
34
39
|
|
35
|
-
|
36
|
-
object.
|
40
|
+
before_validation do |object|
|
41
|
+
object.run_before_validation = true
|
37
42
|
end
|
38
|
-
|
39
|
-
object.
|
43
|
+
after_validation do |object|
|
44
|
+
object.run_after_validation = true
|
40
45
|
end
|
41
46
|
end
|
42
47
|
|
@@ -98,6 +103,14 @@ describe CouchRest::Model::CastedModel do
|
|
98
103
|
@obj.sub_models << {:title => 'test'}
|
99
104
|
@obj.sub_models.first.title.should eql('test')
|
100
105
|
end
|
106
|
+
it "should be empty intitally (without params)" do
|
107
|
+
@obj.param_free_sub_models.should_not be_nil
|
108
|
+
@obj.param_free_sub_models.should be_empty
|
109
|
+
end
|
110
|
+
it "should be updatable using a hash (without params)" do
|
111
|
+
@obj.param_free_sub_models << {:title => 'test'}
|
112
|
+
@obj.param_free_sub_models.first.title.should eql('test')
|
113
|
+
end
|
101
114
|
end
|
102
115
|
|
103
116
|
describe "casted as attribute" do
|
@@ -284,6 +297,11 @@ describe CouchRest::Model::CastedModel do
|
|
284
297
|
@toy2.errors.should be_empty
|
285
298
|
@toy3.errors.should_not be_empty
|
286
299
|
end
|
300
|
+
|
301
|
+
it "should not use dperecated ActiveModel options" do
|
302
|
+
ActiveSupport::Deprecation.should_not_receive(:warn)
|
303
|
+
@cat.should_not be_valid
|
304
|
+
end
|
287
305
|
end
|
288
306
|
|
289
307
|
describe "on a casted model property" do
|
@@ -423,15 +441,15 @@ describe CouchRest::Model::CastedModel do
|
|
423
441
|
end
|
424
442
|
|
425
443
|
describe "validate" do
|
426
|
-
it "should run
|
427
|
-
@model.
|
444
|
+
it "should run before_validation before validating" do
|
445
|
+
@model.run_before_validation.should be_nil
|
428
446
|
@model.should be_valid
|
429
|
-
@model.
|
447
|
+
@model.run_before_validation.should be_true
|
430
448
|
end
|
431
|
-
it "should run
|
432
|
-
@model.
|
449
|
+
it "should run after_validation after validating" do
|
450
|
+
@model.run_after_validation.should be_nil
|
433
451
|
@model.should be_valid
|
434
|
-
@model.
|
452
|
+
@model.run_after_validation.should be_true
|
435
453
|
end
|
436
454
|
end
|
437
455
|
end
|
@@ -85,12 +85,12 @@ describe "Proxy Class" do
|
|
85
85
|
end
|
86
86
|
it "should get first" do
|
87
87
|
u = @us.first
|
88
|
-
u.
|
88
|
+
u.should == @us.all.first
|
89
89
|
end
|
90
90
|
|
91
91
|
it "should get last" do
|
92
92
|
u = @us.last
|
93
|
-
u.
|
93
|
+
u.should == @us.all.last
|
94
94
|
end
|
95
95
|
|
96
96
|
it "should set database on first retreived document" do
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
2
|
+
require File.join(FIXTURE_PATH, 'more', 'article')
|
3
|
+
|
4
|
+
describe "Collections" do
|
5
|
+
|
6
|
+
before(:all) do
|
7
|
+
reset_test_db!
|
8
|
+
Article.refresh_design_doc
|
9
|
+
titles = ["very uniq one", "really interesting", "some fun",
|
10
|
+
"really awesome", "crazy bob", "this rocks", "super rad"]
|
11
|
+
titles.each_with_index do |title,i|
|
12
|
+
a = Article.new(:title => title, :date => Date.today)
|
13
|
+
a.save
|
14
|
+
end
|
15
|
+
|
16
|
+
titles = ["yesterday very uniq one", "yesterday really interesting", "yesterday some fun",
|
17
|
+
"yesterday really awesome", "yesterday crazy bob", "yesterday this rocks"]
|
18
|
+
titles.each_with_index do |title,i|
|
19
|
+
a = Article.new(:title => title, :date => Date.today - 1)
|
20
|
+
a.save
|
21
|
+
end
|
22
|
+
end
|
23
|
+
it "should return a proxy that looks like an array of 7 Article objects" do
|
24
|
+
articles = Article.collection_proxy_for('Article', 'by_date', :descending => true,
|
25
|
+
:key => Date.today, :include_docs => true)
|
26
|
+
articles.class.should == Array
|
27
|
+
articles.size.should == 7
|
28
|
+
end
|
29
|
+
it "should provide a class method for paginate" do
|
30
|
+
articles = Article.paginate(:design_doc => 'Article', :view_name => 'by_date',
|
31
|
+
:per_page => 3, :descending => true, :key => Date.today, :include_docs => true)
|
32
|
+
articles.size.should == 3
|
33
|
+
|
34
|
+
articles = Article.paginate(:design_doc => 'Article', :view_name => 'by_date',
|
35
|
+
:per_page => 3, :page => 2, :descending => true, :key => Date.today, :include_docs => true)
|
36
|
+
articles.size.should == 3
|
37
|
+
|
38
|
+
articles = Article.paginate(:design_doc => 'Article', :view_name => 'by_date',
|
39
|
+
:per_page => 3, :page => 3, :descending => true, :key => Date.today, :include_docs => true)
|
40
|
+
articles.size.should == 1
|
41
|
+
end
|
42
|
+
it "should provide a class method for paginated_each" do
|
43
|
+
options = { :design_doc => 'Article', :view_name => 'by_date',
|
44
|
+
:per_page => 3, :page => 1, :descending => true, :key => Date.today,
|
45
|
+
:include_docs => true }
|
46
|
+
Article.paginated_each(options) do |a|
|
47
|
+
a.should_not be_nil
|
48
|
+
end
|
49
|
+
end
|
50
|
+
it "should provide a class method to get a collection for a view" do
|
51
|
+
articles = Article.find_all_article_details(:key => Date.today)
|
52
|
+
articles.class.should == Array
|
53
|
+
articles.size.should == 7
|
54
|
+
end
|
55
|
+
it "should get a subset of articles using paginate" do
|
56
|
+
articles = Article.collection_proxy_for('Article', 'by_date', :key => Date.today, :include_docs => true)
|
57
|
+
articles.paginate(:page => 1, :per_page => 3).size.should == 3
|
58
|
+
articles.paginate(:page => 2, :per_page => 3).size.should == 3
|
59
|
+
articles.paginate(:page => 3, :per_page => 3).size.should == 1
|
60
|
+
end
|
61
|
+
it "should get all articles, a few at a time, using paginated each" do
|
62
|
+
articles = Article.collection_proxy_for('Article', 'by_date', :key => Date.today, :include_docs => true)
|
63
|
+
articles.paginated_each(:per_page => 3) do |a|
|
64
|
+
a.should_not be_nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should raise an exception if design_doc is not provided" do
|
69
|
+
lambda{Article.collection_proxy_for(nil, 'by_date')}.should raise_error
|
70
|
+
lambda{Article.paginate(:view_name => 'by_date')}.should raise_error
|
71
|
+
end
|
72
|
+
it "should raise an exception if view_name is not provided" do
|
73
|
+
lambda{Article.collection_proxy_for('Article', nil)}.should raise_error
|
74
|
+
lambda{Article.paginate(:design_doc => 'Article')}.should raise_error
|
75
|
+
end
|
76
|
+
it "should be able to span multiple keys" do
|
77
|
+
articles = Article.collection_proxy_for('Article', 'by_date', :startkey => Date.today - 1, :endkey => Date.today, :include_docs => true)
|
78
|
+
articles.paginate(:page => 1, :per_page => 3).size.should == 3
|
79
|
+
articles.paginate(:page => 3, :per_page => 3).size.should == 3
|
80
|
+
articles.paginate(:page => 5, :per_page => 3).size.should == 1
|
81
|
+
end
|
82
|
+
it "should pass database parameter to pager" do
|
83
|
+
proxy = mock(:proxy)
|
84
|
+
proxy.stub!(:paginate)
|
85
|
+
::CouchRest::Model::Collection::CollectionProxy.should_receive(:new).with('database', anything(), anything(), anything(), anything()).and_return(proxy)
|
86
|
+
Article.paginate(:design_doc => 'Article', :view_name => 'by_date', :database => 'database')
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|