active_collection 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,6 +3,123 @@
3
3
  Lazy-loaded Array-like collections of records.
4
4
  Compatible with will_paginate.
5
5
 
6
+ == Example
7
+
8
+ A quick example:
9
+
10
+ If you have a model
11
+
12
+ class Beer < ActiveRecord::Base
13
+ end
14
+
15
+ You can make ActiveCollections of Beers like so:
16
+
17
+ class BeerCollection < ActiveCollection::Base
18
+ end
19
+
20
+ Or a more complex version:
21
+
22
+ class BeerCollection < ActiveCollection::Base
23
+
24
+ scope :geolocation
25
+ scope :by_brewery
26
+ order_by "distance ASC"
27
+
28
+ def names
29
+ map(&:name)
30
+ end
31
+
32
+ protected
33
+
34
+ def geolocation
35
+ if params[:lat] && params[:lng]
36
+ { :origin => [params[:lat], params[:lng]], :within => params[:radius] || 50 }
37
+ end
38
+ end
39
+
40
+ def by_brewery
41
+ if params[:brewery_id]
42
+ { :conditions => { :brewery_id => params[:brewery_id] } }
43
+ end
44
+ end
45
+ end
46
+
47
+ And you would use it like so:
48
+
49
+ beers = BeerCollection.new(:lat => 38.1234, :lng => -117.6543)
50
+
51
+ # All of these are lazy loaded only when they're needed.
52
+ beers.size # => Beer.count(:origin => [38.1234, -117.6543], :within => 50)
53
+ beers.each # => Beer.all(:origin => [38.1234, -117.6543], :within => 50, :order => "distance ASC") and yields each record
54
+
55
+ ==== Custom conditions
56
+
57
+ You can specify anything you want for conditions using the scope, find_scope, and count_scope class methods. Conditions on the fly is on my road map.
58
+
59
+ brewery_beers = BeerCollection.new(:brewery_id => 1)
60
+ brewery_beers.to_a # Beer.all(:conditions => {:brewery_id => 1}) => [Beer, Beer, Beer, ...]
61
+ brewery_beers.size # Does not load count, just takes the size of the loaded collection.
62
+ brewery_beers.names # => ["La Folie", "1554", ...]
63
+
64
+ ==== Pagination
65
+
66
+ ActiveCollections are fully will_paginate compliant.
67
+
68
+ paginated_beers = brewery_beers.paginate
69
+ paginated_beers.size # => size of this page only (doesn't query if already loaded)
70
+ paginated_beers.total_entries # => size of the entire collection without paging. (performs a database lookup if it can't be inferred by the collection size)
71
+ paginated_beers.total_pages
72
+ paginated_beers.next_page_collection # => new BeerCollection for page 2. Again, lazily-loaded.
73
+
74
+ ==== Includes
75
+
76
+ Specify eager loading for a collection.
77
+
78
+ beers.include(:brewery) # => new collection that will eager load Brewery association when it loads.
79
+
80
+ Includes can also be specified in the class along with order. Anything specified on the class will combine using active record's rules (merge includes, overwrite order).
81
+
82
+ class BeerCollection < ActiveCollection::Base
83
+ includes :brewery => :owner
84
+ order_by "name asc"
85
+
86
+ # ...
87
+ end
88
+
89
+ == Usage
90
+
91
+ I tend to use this in my index action in a controller by just passing in params.
92
+
93
+ def index
94
+ @beers = BeerCollection.new(params)
95
+ end
96
+
97
+ It will automatically take care of paging. You can also pass the collection itself to the index named route to pass along the params necessary to link to the collection.
98
+
99
+ beers_path(@beers) # => Includes the right options for paging and any specified order or search query.
100
+
101
+ == Coming Soon
102
+
103
+ ==== Search Integration
104
+
105
+ This can already be done by overloading load_collection and load_count in your collection.
106
+
107
+ I have sphinx and solr searching integrated on another project but I've yet to abstract it. Probably will work something like this:
108
+
109
+ BeerCollection.new(:q => "search term")
110
+
111
+ and then you specify searchability like so:
112
+
113
+ class BeerCollection < ActiveCollection::Base
114
+ # It could possibly auto-configure by looking at what search libraries are loaded.
115
+ # Note: this doesn't exist yet.
116
+ search_on :q, :using => :thinking_sphinx
117
+ end
118
+
119
+ ==== Geolocation Integration
120
+
121
+ This can already be done as shown above, but I'd like it to be knowledgeable of the available geolocation libraries like Geokit and also support local search with solr and sphinx.
122
+
6
123
  == Copyright
7
124
 
8
125
  Copyright (c) 2009 Martin Emde. See LICENSE for details.
@@ -1,4 +1,4 @@
1
1
  ---
2
- :patch: 4
2
+ :patch: 5
3
3
  :major: 0
4
4
  :minor: 2
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{active_collection}
8
- s.version = "0.2.4"
8
+ s.version = "0.2.5"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Martin Emde"]
12
- s.date = %q{2009-10-12}
12
+ s.date = %q{2009-10-13}
13
13
  s.description = %q{A lazy-loading, Array-like collection proxy for ActiveRecord that understands conditions and paging.}
14
14
  s.email = %q{martin.emde@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -35,7 +35,9 @@ Gem::Specification.new do |s|
35
35
  "lib/active_collection/scope.rb",
36
36
  "lib/active_collection/serialization.rb",
37
37
  "spec/base_spec.rb",
38
+ "spec/includes_spec.rb",
38
39
  "spec/member_class_spec.rb",
40
+ "spec/order_spec.rb",
39
41
  "spec/pagination_spec.rb",
40
42
  "spec/proxy_spec.rb",
41
43
  "spec/spec.opts",
@@ -49,7 +51,9 @@ Gem::Specification.new do |s|
49
51
  s.summary = %q{A lazy-loading, Array-like collection proxy for ActiveRecord that understands conditions and paging.}
50
52
  s.test_files = [
51
53
  "spec/base_spec.rb",
54
+ "spec/includes_spec.rb",
52
55
  "spec/member_class_spec.rb",
56
+ "spec/order_spec.rb",
53
57
  "spec/pagination_spec.rb",
54
58
  "spec/proxy_spec.rb",
55
59
  "spec/spec_helper.rb"
@@ -53,7 +53,7 @@ module ActiveCollection
53
53
 
54
54
  # dup that doesn't include the collection if it's loaded
55
55
  def unloading_dup
56
- d = super
56
+ d = dup
57
57
  d.unload!
58
58
  yield d if block_given?
59
59
  d
@@ -8,49 +8,77 @@ module ActiveCollection
8
8
  end
9
9
  end
10
10
 
11
+ # def self.before_save(*methods, &block)
12
+ # callbacks = CallbackChain.build(:before_save, *methods, &block)
13
+ # @before_save_callbacks ||= CallbackChain.new
14
+ # @before_save_callbacks.concat callbacks
15
+ # end
16
+ #
17
+ # def self.before_save_callback_chain
18
+ # @before_save_callbacks ||= CallbackChain.new
19
+ #
20
+ # if superclass.respond_to?(:before_save_callback_chain)
21
+ # CallbackChain.new(
22
+ # superclass.before_save_callback_chain +
23
+ # @before_save_callbacks
24
+ # )
25
+ # else
26
+ # @before_save_callbacks
27
+ # end
28
+ # end
29
+
11
30
  module ClassMethods
12
- def includes(*includes)
13
- write_inheritable_attribute(:default_includes, includes)
31
+ def includes(*new_includes)
32
+ @default_includes = merge_includes(@default_includes || [], new_includes)
14
33
  end
15
34
 
16
35
  def default_includes
17
- read_inheritable_attribute(:default_includes) || []
36
+ @default_includes ||= []
37
+ if superclass != ActiveCollection::Base
38
+ merge_includes(superclass.default_includes, @default_includes)
39
+ else
40
+ @default_includes
41
+ end
42
+ end
43
+
44
+ def merge_includes(a, b)
45
+ (safe_to_array(a) + safe_to_array(b)).flatten.uniq
46
+ end
47
+
48
+ protected
49
+
50
+ # Taken from ActiveRecord::Base
51
+ #
52
+ # Object#to_a is deprecated, though it does have the desired behavior
53
+ def safe_to_array(o)
54
+ case o
55
+ when NilClass
56
+ []
57
+ when Array
58
+ o
59
+ else
60
+ [o]
61
+ end
18
62
  end
19
63
  end
20
64
 
21
65
  def includes
22
- @includes ||= self.class.default_includes
66
+ @includes ||= []
23
67
  end
24
68
 
25
69
  def include(*new_includes)
26
- ac = unloading_dup
27
- ac.include! *new_includes
28
- ac
70
+ unloading_dup { |ac| ac.include! *new_includes }
29
71
  end
30
72
 
31
73
  def include!(*new_includes)
32
74
  raise_if_loaded
33
- @includes = (safe_to_array(new_includes) + safe_to_array(includes)).uniq
75
+ @includes = self.class.merge_includes(includes, new_includes)
34
76
  end
35
77
 
36
78
  def include_options
37
- { :include => @includes } unless @includes.blank?
79
+ incs = self.class.merge_includes(self.class.default_includes, includes)
80
+ { :include => incs } unless incs.blank?
38
81
  end
39
82
 
40
- protected
41
-
42
- # Taken from ActiveRecord::Base
43
- #
44
- # Object#to_a is deprecated, though it does have the desired behavior
45
- def safe_to_array(o)
46
- case o
47
- when NilClass
48
- []
49
- when Array
50
- o
51
- else
52
- [o]
53
- end
54
- end
55
83
  end
56
84
  end
@@ -17,8 +17,8 @@ module ActiveCollection
17
17
  # end
18
18
  #
19
19
  # This will use the class Normal to do counts and finds.
20
- def model(class_name)
21
- (@model_class_name = class_name) && @model_class = nil
20
+ def model(model_name)
21
+ (@model_class_name = model_name) && @model_class = nil
22
22
  end
23
23
 
24
24
  # The actual member class.
@@ -42,10 +42,10 @@ module ActiveCollection
42
42
  model_class.human_name(*args).pluralize
43
43
  end
44
44
 
45
- protected
46
-
47
45
  def model_class_name
48
- @model_class_name || name.sub(/Collection$/,'')
46
+ @model_class_name ||
47
+ (superclass != ActiveCollection::Base && superclass.model_class_name) ||
48
+ name.sub(/Collection$/,'')
49
49
  end
50
50
  end
51
51
 
@@ -8,6 +8,16 @@ module ActiveCollection
8
8
  end
9
9
  end
10
10
 
11
+ module ClassMethods
12
+ def order_by(order = "id ASC")
13
+ @order = order
14
+ end
15
+
16
+ def default_order
17
+ @order || (superclass != ActiveCollection::Base && superclass.default_order) || nil
18
+ end
19
+ end
20
+
11
21
  def order
12
22
  @order ||= self.class.default_order
13
23
  end
@@ -24,17 +34,8 @@ module ActiveCollection
24
34
  end
25
35
 
26
36
  def order_options
27
- { :order => order } if order
28
- end
29
-
30
- module ClassMethods
31
- def order_by(order = "id ASC")
32
- write_inheritable_attribute(:default_order, order)
33
- end
34
-
35
- def default_order
36
- read_inheritable_attribute(:default_order) || nil
37
- end
37
+ ord = @order || self.class.default_order
38
+ { :order => ord } if ord
38
39
  end
39
40
  end
40
41
  end
@@ -63,6 +63,19 @@ module ActiveCollection
63
63
  @current_page = pg
64
64
  end
65
65
 
66
+ # return a paginated collection if it isn't already paginated.
67
+ # returns self if already paginated.
68
+ def paginate
69
+ paginated?? self : page(1)
70
+ end
71
+
72
+ # forces pagination of self, raising if already loaded.
73
+ # returns current_page if the collection is now paginated
74
+ # returns nil if already paginated
75
+ def paginate!
76
+ paginated?? nil : page!(1)
77
+ end
78
+
66
79
  # Helper method that is true when someone tries to fetch a page with a
67
80
  # larger number than the last page. Can be used in combination with flashes
68
81
  # and redirecting.
@@ -134,20 +147,6 @@ module ActiveCollection
134
147
  (total_entries / per_page.to_f).ceil
135
148
  end
136
149
 
137
- # return a paginated collection if it isn't already paginated.
138
- # returns self if already paginated.
139
- def paginate
140
- paginated?? self : page(current_page || 1)
141
- end
142
-
143
- # forces pagination of self, raising if already loaded.
144
- # returns current_page if the collection is now paginated
145
- # returns nil if already paginated
146
- def paginate!
147
- raise_if_loaded
148
- current_page ? nil : @current_page = 1
149
- end
150
-
151
150
  # if the collection has a page parameter
152
151
  def paginated?
153
152
  current_page && current_page > 0
@@ -0,0 +1,143 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ class Beer
4
+ end
5
+
6
+ class IncludedBeerCollection < ActiveCollection::Base
7
+ model "Beer"
8
+ includes :brewery
9
+ end
10
+
11
+ class InheritedNotIncludedBeerCollection < IncludedBeerCollection
12
+ end
13
+
14
+ class InheritedIncludedBeerCollection < IncludedBeerCollection
15
+ includes :imbibes => :user
16
+ end
17
+
18
+ class NotIncludedBeerCollection < ActiveCollection::Base
19
+ model "Beer"
20
+ end
21
+
22
+ class MultipleIncludesBeerCollection < ActiveCollection::Base
23
+ model "Beer"
24
+ includes :brewery
25
+ includes :imbibes
26
+ end
27
+
28
+ describe ActiveCollection, "(includes)" do
29
+ context "(without class includes)" do
30
+ subject { NotIncludedBeerCollection.new }
31
+
32
+ it "does not have any includes" do
33
+ Beer.should_receive(:all).with({}).and_return([])
34
+ subject.to_a
35
+ end
36
+
37
+ it "adds includes added to an instance" do
38
+ subject.include! :tags
39
+ Beer.should_receive(:all).with(:include => [:tags]).and_return([])
40
+ subject.to_a
41
+ end
42
+
43
+ it "creates a new object with the includes on #include" do
44
+ col = subject.include :tags
45
+ Beer.should_receive(:all).with(:include => [:tags]).and_return([])
46
+ col.to_a
47
+ end
48
+
49
+ it "doesn't affect the existing object on #include" do
50
+ col = subject.include :tags
51
+ Beer.should_receive(:all).with({}).and_return([])
52
+ subject.to_a
53
+ end
54
+
55
+ it "doesn't choke on nil include" do
56
+ col = subject.include nil
57
+ Beer.should_receive(:all).with({}).and_return([])
58
+ subject.to_a
59
+ end
60
+ end
61
+
62
+ context "(with class includes)" do
63
+ subject { IncludedBeerCollection.new }
64
+
65
+ it "includes any class level includes with collection loads" do
66
+ Beer.should_receive(:all).with(:include => [:brewery]).and_return([])
67
+ subject.to_a
68
+ end
69
+
70
+ it "does not send includes with count" do
71
+ Beer.should_receive(:count).with({}).and_return(0)
72
+ subject.empty?
73
+ end
74
+
75
+ it "merges includes added to an instance with default includes" do
76
+ subject.include! :tags
77
+ Beer.should_receive(:all).with(:include => [:brewery, :tags]).and_return([])
78
+ subject.to_a
79
+ end
80
+
81
+ it "doesn't mind includes being given as an array" do
82
+ subject.include! [:tags]
83
+ Beer.should_receive(:all).with(:include => [:brewery, :tags]).and_return([])
84
+ subject.to_a
85
+ end
86
+ end
87
+
88
+ context "(inherited from a class with includes)" do
89
+ subject { InheritedNotIncludedBeerCollection.new }
90
+
91
+ it "includes superclass includes with collection loads" do
92
+ Beer.should_receive(:all).with(:include => [:brewery]).and_return([])
93
+ subject.to_a
94
+ end
95
+
96
+ it "does not send includes with count" do
97
+ Beer.should_receive(:count).with({}).and_return(0)
98
+ subject.empty?
99
+ end
100
+
101
+ it "merges includes added to an instance with default includes" do
102
+ subject.include! :tags
103
+ Beer.should_receive(:all).with(:include => [:brewery, :tags]).and_return([])
104
+ subject.to_a
105
+ end
106
+
107
+ it "creates a new object with the includes on #include" do
108
+ col = subject.include :tags
109
+ Beer.should_receive(:all).with(:include => [:brewery, :tags]).and_return([])
110
+ col.to_a
111
+ end
112
+ end
113
+
114
+ context "(inherited adding includes)" do
115
+ subject { InheritedIncludedBeerCollection.new }
116
+
117
+ it "merges superclass includes on collection load" do
118
+ Beer.should_receive(:all).with(:include => [:brewery, {:imbibes => :user}]).and_return([])
119
+ subject.to_a
120
+ end
121
+
122
+ it "merges includes added to an instance with default includes" do
123
+ subject.include! :tags
124
+ Beer.should_receive(:all).with(:include => [:brewery, {:imbibes => :user}, :tags]).and_return([])
125
+ subject.to_a
126
+ end
127
+ end
128
+
129
+ context "(multiple includes)" do
130
+ subject { MultipleIncludesBeerCollection.new }
131
+
132
+ it "merges includes on collection load" do
133
+ Beer.should_receive(:all).with(:include => [:brewery, :imbibes]).and_return([])
134
+ subject.to_a
135
+ end
136
+
137
+ it "merges includes added to an instance with default includes" do
138
+ subject.include! :tags
139
+ Beer.should_receive(:all).with(:include => [:brewery, :imbibes, :tags]).and_return([])
140
+ subject.to_a
141
+ end
142
+ end
143
+ end
@@ -1,30 +1,37 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
- class Beer
3
+ class Model
4
4
  def self.human_name(*args)
5
- "Beer"
5
+ "Model"
6
6
  end
7
7
 
8
8
  def self.table_name
9
- "beers"
9
+ "models"
10
10
  end
11
11
  end
12
12
 
13
- class BeerCollection < ActiveCollection::Base
13
+ class ModelCollection < ActiveCollection::Base
14
14
  end
15
15
 
16
- class DunkelBeer
16
+ class SpecialModel
17
17
  def self.human_name(*args)
18
- "Dunkel Beer"
18
+ "Special Model"
19
19
  end
20
20
 
21
21
  def self.table_name
22
- "dunkel_beers"
22
+ "special_models"
23
23
  end
24
24
  end
25
25
 
26
- class DarkBeerCollection < ActiveCollection::Base
27
- model "DunkelBeer"
26
+ class SpecialCollection < ActiveCollection::Base
27
+ model "SpecialModel"
28
+ end
29
+
30
+ class InheritedSpecialCollection < SpecialCollection
31
+ end
32
+
33
+ class OverloadedInheritedSpecialCollection < SpecialCollection
34
+ model "Model"
28
35
  end
29
36
 
30
37
  class BrokenCollection < ActiveCollection::Base
@@ -32,38 +39,54 @@ end
32
39
 
33
40
  describe ActiveCollection do
34
41
  context "(with standard name)" do
35
- subject { BeerCollection.new }
42
+ subject { ModelCollection.new }
36
43
 
37
44
  it "has the correct model_class" do
38
- subject.model_class.should == Beer
45
+ subject.model_class.should == Model
39
46
  end
40
47
 
41
48
  it "retrieves table_name from member class" do
42
- subject.table_name.should == "beers"
49
+ subject.table_name.should == "models"
43
50
  end
44
51
 
45
52
  it "retrieves human_name from member class and pluralizes" do
46
- subject.human_name(:locale => 'en-us').should == "Beers"
53
+ subject.human_name(:locale => 'en-us').should == "Models"
47
54
  end
48
55
  end
49
56
 
50
57
  context "(with model)" do
51
- subject { DarkBeerCollection.new }
58
+ subject { SpecialCollection.new }
52
59
 
53
60
  it "uses the correct model class" do
54
- subject.model_class.should == DunkelBeer
61
+ subject.model_class.should == SpecialModel
55
62
  end
56
63
 
57
64
  it "doesn't affect other classes" do
58
- BeerCollection.new.model_class.should == Beer
65
+ ModelCollection.new.model_class.should == Model
59
66
  end
60
67
 
61
68
  it "retrieves table_name from member class" do
62
- subject.table_name.should == "dunkel_beers"
69
+ subject.table_name.should == "special_models"
63
70
  end
64
71
 
65
72
  it "retrieves human_name from member class and pluralizes" do
66
- subject.human_name(:locale => 'en-us').should == "Dunkel Beers"
73
+ subject.human_name(:locale => 'en-us').should == "Special Models"
74
+ end
75
+ end
76
+
77
+ context "(inherited and not overloaded)" do
78
+ subject { InheritedSpecialCollection.new }
79
+
80
+ it "maintains the same model class" do
81
+ subject.model_class.should == SpecialModel
82
+ end
83
+ end
84
+
85
+ context "(inherited and overloaded)" do
86
+ subject { OverloadedInheritedSpecialCollection.new }
87
+
88
+ it "maintains the same model class" do
89
+ subject.model_class.should == Model
67
90
  end
68
91
  end
69
92
 
@@ -0,0 +1,99 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ class Beer
4
+ end
5
+
6
+ class OrderedBeerCollection < ActiveCollection::Base
7
+ model "Beer"
8
+ order_by "name"
9
+ end
10
+
11
+ class InheritedOrderedBeerCollection < OrderedBeerCollection
12
+ end
13
+
14
+ class OverloadedInheritedOrderedBeerCollection < OrderedBeerCollection
15
+ order_by "created_at DESC"
16
+ end
17
+
18
+ class NotOrderedBeerCollection < ActiveCollection::Base
19
+ model "Beer"
20
+ end
21
+
22
+ describe ActiveCollection, "(order_by)" do
23
+ context "(without class order_by)" do
24
+ subject { NotOrderedBeerCollection.new }
25
+
26
+ it "does not have any order on load" do
27
+ Beer.should_receive(:all).with({}).and_return([])
28
+ subject.to_a
29
+ end
30
+
31
+ it "adds order on instance" do
32
+ subject.order_by! "id DESC"
33
+ Beer.should_receive(:all).with(:order => "id DESC").and_return([])
34
+ subject.to_a
35
+ end
36
+
37
+ it "creates a new object with the order_by on #order_by" do
38
+ col = subject.order_by "id DESC"
39
+ Beer.should_receive(:all).with(:order => "id DESC").and_return([])
40
+ col.to_a
41
+ end
42
+
43
+ it "doesn't affect the existing object on #order_by" do
44
+ col = subject.order_by "id DESC"
45
+ Beer.should_receive(:all).with({}).and_return([])
46
+ subject.to_a
47
+ end
48
+ end
49
+
50
+ context "(with class order_by)" do
51
+ subject { OrderedBeerCollection.new }
52
+
53
+ it "sends order when collection loads" do
54
+ Beer.should_receive(:all).with(:order => "name").and_return([])
55
+ subject.to_a
56
+ end
57
+
58
+ it "does not send order with count" do
59
+ Beer.should_receive(:count).with({}).and_return(0)
60
+ subject.empty?
61
+ end
62
+
63
+ it "overloads order when added to instance" do
64
+ subject.order_by! "id DESC"
65
+ Beer.should_receive(:all).with(:order => "id DESC").and_return([])
66
+ subject.to_a
67
+ end
68
+ end
69
+
70
+ context "(inherited from a class with order_by)" do
71
+ subject { InheritedOrderedBeerCollection.new }
72
+
73
+ it "sends superclass order on collection loads" do
74
+ Beer.should_receive(:all).with(:order => "name").and_return([])
75
+ subject.to_a
76
+ end
77
+
78
+ it "overloads order when added to instance" do
79
+ subject.order_by! "id DESC"
80
+ Beer.should_receive(:all).with(:order => "id DESC").and_return([])
81
+ subject.to_a
82
+ end
83
+ end
84
+
85
+ context "(inherited adding order_by)" do
86
+ subject { OverloadedInheritedOrderedBeerCollection.new }
87
+
88
+ it "overloads superclasses' order" do
89
+ Beer.should_receive(:all).with(:order => "created_at DESC").and_return([])
90
+ subject.to_a
91
+ end
92
+
93
+ it "overloads order when added to instance" do
94
+ subject.order_by! "id DESC"
95
+ Beer.should_receive(:all).with(:order => "id DESC").and_return([])
96
+ subject.to_a
97
+ end
98
+ end
99
+ end
@@ -113,10 +113,10 @@ describe ActiveCollection do
113
113
  subject.total_entries
114
114
  end
115
115
 
116
- it "raises on attempt to force paginate after already loaded" do
116
+ it "raises on attempt to force a page number after already loaded" do
117
117
  subject.to_a
118
118
  subject.should be_loaded
119
- lambda { subject.paginate! }.should raise_error(ActiveCollection::AlreadyLoadedError)
119
+ lambda { subject.page!(3) }.should raise_error(ActiveCollection::AlreadyLoadedError)
120
120
  end
121
121
 
122
122
  it "returns the same record on 'soft' paginate when already paginated" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_collection
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Emde
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-12 00:00:00 -07:00
12
+ date: 2009-10-13 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -50,7 +50,9 @@ files:
50
50
  - lib/active_collection/scope.rb
51
51
  - lib/active_collection/serialization.rb
52
52
  - spec/base_spec.rb
53
+ - spec/includes_spec.rb
53
54
  - spec/member_class_spec.rb
55
+ - spec/order_spec.rb
54
56
  - spec/pagination_spec.rb
55
57
  - spec/proxy_spec.rb
56
58
  - spec/spec.opts
@@ -85,7 +87,9 @@ specification_version: 3
85
87
  summary: A lazy-loading, Array-like collection proxy for ActiveRecord that understands conditions and paging.
86
88
  test_files:
87
89
  - spec/base_spec.rb
90
+ - spec/includes_spec.rb
88
91
  - spec/member_class_spec.rb
92
+ - spec/order_spec.rb
89
93
  - spec/pagination_spec.rb
90
94
  - spec/proxy_spec.rb
91
95
  - spec/spec_helper.rb