couch_view 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,142 @@
1
+ Feature: CouchView::Config::Conditions
2
+
3
+ CouchView::Config::Conditions are a simple way to keep track of the conditions in a view configuration.
4
+
5
+ h2. Instantiation
6
+
7
+ To create a new CouchView::Config::Conditions instance, simply call ".new" on it.
8
+
9
+ During instantiation, you can pass some modules to it representing conditions:
10
+
11
+ conditions_config = CouchView::Config::Conditions.new Condition1, Condition2
12
+
13
+ h2. Adding conditions
14
+
15
+ You can add more conditions to it by passing them to the "add_conditions":
16
+
17
+ conditions_config.add_conditions Condition3, Condition4
18
+
19
+ If you add a condition that's namespaced, the name of the condition will be defaulted to the unqualified class name:
20
+
21
+ conditions_config.add_condition Namespace::Subspace::ConditionX
22
+
23
+ conditions_Config.conditions[:condition_x] #==> Namespace::Subspace::ConditionX
24
+
25
+ h2. Adding named conditions
26
+
27
+ You can add named conditions to your config by calling a method on them with the name you want to reference the condition by:
28
+
29
+ conditions_config.published Conditions::Published
30
+
31
+ h2. Getting all of the conditions
32
+
33
+ If you call the "conditions" method without any arguments, you'll receive a hash of all of the conditions. The key is the name of a condition, the value is the condition module.
34
+
35
+ #conditions_config.conditions
36
+ # #==> {
37
+ # :condition1 => Condition1,
38
+ # :condition2 => Condition2,
39
+ # :condition3 => Condition3,
40
+ # :condition4 => Condition4,
41
+ # :published => Conditions::Published
42
+ # }
43
+
44
+
45
+ Scenario: Conditions passed during CouchView::Config::Conditions instantiation
46
+ Given the following conditions:
47
+ """
48
+ module Published; end
49
+ module Visible; end
50
+ """
51
+
52
+ When I instantiate a CouchView::Config::Conditions object and pass those condition modules to it:
53
+ """
54
+ @conditions_config = CouchView::Config::Conditions.new Published, Visible
55
+ """
56
+
57
+ Then the "conditions" method on the config should return those conditions:
58
+ """
59
+ @conditions_config.conditions.should == {
60
+ :published => Published,
61
+ :visible => Visible
62
+ }
63
+ """
64
+
65
+
66
+ Scenario: Adding conditions after instantiation
67
+ Given the following conditions:
68
+ """
69
+ module Published; end
70
+ module Visible; end
71
+ """
72
+
73
+ And a CouchView::Config::Conditions object:
74
+ """
75
+ @conditions_config = CouchView::Config::Conditions.new
76
+ """
77
+
78
+ When I pass those condition modules to the condition config object's "add_conditions" method:
79
+ """
80
+ @conditions_config.add_conditions Published, Visible
81
+ """
82
+
83
+ Then the "conditions" method on the config should return those conditions:
84
+ """
85
+ @conditions_config.conditions.should == {
86
+ :published => Published,
87
+ :visible => Visible
88
+ }
89
+ """
90
+
91
+ Scenario: Creating named conditions
92
+ Given the following conditions:
93
+ """
94
+ module Published; end
95
+ module Visible; end
96
+ """
97
+
98
+ And a CouchView::Config::Conditions object:
99
+ """
100
+ @conditions_config = CouchView::Config::Conditions.new
101
+ """
102
+
103
+ When I add those conditions to my config with custom names:
104
+ """
105
+ @conditions_config.filter_by_published Published
106
+ @conditions_config.filter_by_visible Visible
107
+ """
108
+
109
+ Then the "conditions" method on the config should return those conditions:
110
+ """
111
+ @conditions_config.conditions.should == {
112
+ :filter_by_published => Published,
113
+ :filter_by_visible => Visible
114
+ }
115
+ """
116
+
117
+ Scenario: Namespaced conditions get unqualified keys
118
+ Given the following conditions:
119
+ """
120
+ module Conditions
121
+ module Published; end
122
+ module Visible; end
123
+ end
124
+ """
125
+
126
+ And a CouchView::Config::Conditions object:
127
+ """
128
+ @conditions_config = CouchView::Config::Conditions.new
129
+ """
130
+
131
+ When I pass those condition modules to the condition config object's "add_conditions" method:
132
+ """
133
+ @conditions_config.add_conditions Conditions::Published, Conditions::Visible
134
+ """
135
+
136
+ Then the "conditions" method on the config should return those conditions:
137
+ """
138
+ @conditions_config.conditions.should == {
139
+ :published => Conditions::Published,
140
+ :visible => Conditions::Visible
141
+ }
142
+ """
@@ -92,11 +92,11 @@ Feature: CouchView::Config
92
92
 
93
93
  config = CouchView::Config.new Article
94
94
  config.conditions Published
95
- config.conditions #==> [Published]
95
+ config.conditions #==> {:published => Published}
96
96
  condig.conditions Visible
97
- config.conditions #==> [Published, Visible]
97
+ config.conditions #==> {:published => Published, :visible => Visible}
98
98
  config.conditions Published
99
- config.conditions #==> [Published, Visible]
99
+ config.conditions #==> {:published => Published, :visible => Visible}
100
100
 
101
101
  @db
102
102
  Scenario: Generating a name based on the properties passed in to map over
@@ -225,7 +225,7 @@ Feature: CouchView::Config
225
225
 
226
226
  Then the conditions should be Published and Visible:
227
227
  """
228
- @config.conditions.should == [Published, Visible]
228
+ @config.conditions.should == {:published => Published, :visible => Visible}
229
229
  """
230
230
 
231
231
  And the view names should include views for published, visible, and published/visible documents:
@@ -267,7 +267,7 @@ Feature: CouchView::Config
267
267
 
268
268
  Then the conditions method on my config should return the conditions specified:
269
269
  """
270
- @config.conditions.should == [Published, Visible]
270
+ @config.conditions.should == {:published => Published, :visible => Visible}
271
271
  """
272
272
 
273
273
  @db
@@ -439,11 +439,11 @@ Feature: CouchView::Config
439
439
  Then adding the same condition multiple times will result in the condition only being added once:
440
440
  """
441
441
  @config.conditions Published
442
- @config.conditions.should == [Published]
442
+ @config.conditions.should == {:published => Published}
443
443
  @config.conditions Visible
444
- @config.conditions.should == [Published, Visible]
444
+ @config.conditions.should == {:published => Published, :visible => Visible}
445
445
  @config.conditions Published
446
- @config.conditions.should == [Published, Visible]
446
+ @config.conditions.should == {:published => Published, :visible => Visible}
447
447
  @config.conditions Visible
448
- @config.conditions.should == [Published, Visible]
448
+ @config.conditions.should == {:published => Published, :visible => Visible}
449
449
  """
@@ -92,6 +92,67 @@ Feature: CouchView
92
92
  ["published_and_visible"]
93
93
  """
94
94
 
95
+
96
+ @focus
97
+ Scenario: Define a map on your model with named conditions
98
+ Given the following conditions:
99
+ """
100
+ module Conditions
101
+ module Published
102
+ def conditions
103
+ "#{super} && doc.published == true"
104
+ end
105
+ end
106
+
107
+ module Visible
108
+ def conditions
109
+ "#{super} && doc.visible == true"
110
+ end
111
+ end
112
+ end
113
+ """
114
+
115
+ When I add them as conditions to a map over my model's label property:
116
+ """
117
+ class Article < CouchRest::Model::Base
118
+ include CouchView
119
+
120
+ property :label
121
+ property :published, TrueClass, :default => false
122
+ property :visible, TrueClass, :default => false
123
+
124
+ map :label do
125
+ conditions do
126
+ filter_by_published Conditions::Published
127
+ filter_by_visible Conditions::Visible
128
+ end
129
+ end
130
+ end
131
+ """
132
+
133
+ And I create visible and published documents:
134
+ """
135
+ Article.create :label => "unpublished"
136
+ Article.create :label => "published", :published => true
137
+ Article.create :label => "visible", :visible => true
138
+ Article.create :label => "published_and_visible", :published => true, :visible => true
139
+ """
140
+
141
+ Then I should be able to query them through my query proxy:
142
+ """
143
+ Article.map_by_label!.collect(&:label).sort.should ==
144
+ ["published", "published_and_visible", "unpublished", "visible"]
145
+
146
+ Article.map_by_label.filter_by_published.get!.collect(&:label).sort.should ==
147
+ ["published", "published_and_visible"]
148
+
149
+ Article.map_by_label.filter_by_visible.get!.collect(&:label).sort.should ==
150
+ ["published_and_visible", "visible"]
151
+
152
+ Article.map_by_label.filter_by_published.filter_by_visible.get!.collect(&:label).sort.should ==
153
+ ["published_and_visible"]
154
+ """
155
+
95
156
 
96
157
  Scenario: Define a map on your model with the `map` class method
97
158
  Given the following map definition:
@@ -354,7 +415,6 @@ Feature: CouchView
354
415
  """
355
416
 
356
417
 
357
- @focus
358
418
  Scenario: Chaining together multiple conditions by defining a map multiple times
359
419
 
360
420
  Given the following model:
@@ -0,0 +1,11 @@
1
+ Given /^a CouchView::Config::Conditions object:$/ do |string|
2
+ eval string
3
+ end
4
+
5
+ When /^I pass those condition modules to the condition config object's .*:$/ do |string|
6
+ eval string
7
+ end
8
+
9
+ When /^I add those conditions to my config with custom names:$/ do |string|
10
+ eval string
11
+ end
@@ -0,0 +1,37 @@
1
+ module CouchView
2
+ class Config
3
+ class Conditions
4
+ attr_reader :conditions
5
+
6
+ def initialize(*conditions)
7
+ @conditions = {}
8
+ add_condition_modules conditions
9
+ end
10
+
11
+ def add_conditions(*args)
12
+ add_condition_modules args
13
+ end
14
+
15
+ alias :add_condition :add_conditions
16
+
17
+ def method_missing(condition_name, *args, &block)
18
+ super if block
19
+ super unless args.count == 1
20
+
21
+ add_condition_module condition_name, args.first
22
+ end
23
+
24
+ private
25
+ def add_condition_modules(condition_modules)
26
+ condition_modules.each do |condition_module|
27
+ condition_name = condition_module.to_s.underscore.gsub(/^.*\/([^\/]+)$/) { $1 }
28
+ add_condition_module condition_name, condition_module
29
+ end
30
+ end
31
+
32
+ def add_condition_module(condition_name, condition_module)
33
+ @conditions[condition_name.to_sym] = condition_module
34
+ end
35
+ end
36
+ end
37
+ end
@@ -4,7 +4,7 @@ module CouchView
4
4
 
5
5
  def initialize(model_class)
6
6
  @model = model_class
7
- @conditions = []
7
+ @conditions = CouchView::Config::Conditions.new
8
8
  end
9
9
 
10
10
  def map(*args, &block)
@@ -20,12 +20,12 @@ module CouchView
20
20
  end
21
21
  end
22
22
 
23
- def conditions(*args)
24
- if args.empty?
25
- @conditions
23
+ def conditions(*args, &block)
24
+ if args.empty? && block.nil?
25
+ @conditions.conditions
26
26
  else
27
- @conditions += args
28
- @conditions.uniq!
27
+ @conditions.add_conditions *args
28
+ @conditions.instance_eval &block if block
29
29
  end
30
30
  end
31
31
 
@@ -57,17 +57,17 @@ module CouchView
57
57
 
58
58
  private
59
59
  def condition_views
60
- all_condition_subsets = @conditions.all_combinations.reject &:empty?
60
+ all_condition_subsets = @conditions.conditions.keys.all_combinations.reject &:empty?
61
61
 
62
62
  all_condition_subsets.reject(&:empty?).inject({}) do |result, condition_combination|
63
63
  condition_combination.sort! {|a,b| a.to_s <=> b.to_s}
64
64
 
65
65
  view_name =
66
66
  "#{base_view_name}_" +
67
- condition_combination.map {|condition| condition.to_s.underscore}.join("_")
67
+ condition_combination.map {|condition| condition.to_s}.join("_")
68
68
 
69
69
  map_instance = @map_class.new @model, *@properties
70
- condition_combination.map { |condition| map_instance.extend condition }
70
+ condition_combination.map { |condition| map_instance.extend @conditions.conditions[condition] }
71
71
 
72
72
  result[view_name.to_sym] = {
73
73
  :map => map_instance.map,
data/lib/couch_view.rb CHANGED
@@ -8,3 +8,4 @@ require 'couch_view/map_property'
8
8
  require 'couch_view/count_proxy'
9
9
  require 'couch_view/query_options'
10
10
  require 'couch_view/array'
11
+ require 'couch_view/conditions'
data/readme.markdown CHANGED
@@ -15,7 +15,7 @@ This gem integrates with the `couchrest_model` gem (version ~> 1.0.0)
15
15
  Install it as a gem:
16
16
 
17
17
  ```sh
18
- $ gem install couch_view
18
+ $ gem install couch_view
19
19
  ```
20
20
 
21
21
  ## Your first view
@@ -25,28 +25,28 @@ Let's imagine that we want to create a map on our model that includes all of the
25
25
  We can start by simply calling the "map" method on our model, passing in the :label property:
26
26
 
27
27
  ```ruby
28
- class Article < CouchRest::Model::Base
29
- include CouchView
30
-
31
- property :label
28
+ class Article < CouchRest::Model::Base
29
+ include CouchView
30
+
31
+ property :label
32
32
 
33
- map :label
34
- end
33
+ map :label
34
+ end
35
35
  ```
36
36
 
37
37
  This will generate a javascript map function that looks like this:
38
38
 
39
39
  ```javascript
40
- function(doc){
41
- if (doc['couchrest-type'] == 'Article')
42
- emit(doc.label, null)
43
- }
40
+ function(doc){
41
+ if (doc['couchrest-type'] == 'Article')
42
+ emit(doc.label, null)
43
+ }
44
44
  ```
45
45
 
46
46
  We can query this map by using the "map_by_label!" method:
47
47
 
48
48
  ```ruby
49
- Article.map_by_label! #==> all of the articles, in order of label
49
+ Article.map_by_label! #==> all of the articles, in order of label
50
50
  ```
51
51
 
52
52
  You can use any of the standard CouchDB query options on this view; see the section "Query Proxy" for more information.
@@ -54,28 +54,28 @@ You can use any of the standard CouchDB query options on this view; see the sect
54
54
  We can also count all of the articles in the "by_label" map using the `count_by_label!` method:
55
55
 
56
56
  ```ruby
57
- Article.count_by_label! #==> 0, assuming we haven't created any articles
57
+ Article.count_by_label! #==> 0, assuming we haven't created any articles
58
58
  ```
59
59
 
60
60
  Next, let's imagine that we'd like to create a view with a compound key: let's index all of the articles in the system by author and created_at:
61
61
 
62
62
  ```ruby
63
- class Article < CouchRest::Model::Base
64
- include CouchView
65
- property :author
66
- timestamps!
63
+ class Article < CouchRest::Model::Base
64
+ include CouchView
65
+ property :author
66
+ timestamps!
67
67
 
68
- map :author, :created_at
69
- end
68
+ map :author, :created_at
69
+ end
70
70
  ```
71
71
 
72
72
  And it's as simple as that. `CouchView` generated the following javascript map function:
73
73
 
74
74
  ```javascript
75
- function(doc){
76
- if (doc['couchrest-type'] == 'Article')
77
- emit([doc.author, doc.created_at], null)
78
- }
75
+ function(doc){
76
+ if (doc['couchrest-type'] == 'Article')
77
+ emit([doc.author, doc.created_at], null)
78
+ }
79
79
  ```
80
80
 
81
81
  We can now iterate over the map using the `map_by_author_and_created_at!` method, and we can count it using the `count_by_author_and_created_at!` method.
@@ -87,48 +87,48 @@ But what if you need to create a more complex view? `CouchView` is your friend h
87
87
  We'll start by creating a map class:
88
88
 
89
89
  ```ruby
90
- class ByCommentCount
91
- include CouchView::Map
92
-
93
- def map
94
- <<-JS
95
- function(doc){
96
- if (#{conditions})
97
- emit(doc.comments.length, null)
98
- }
99
- JS
100
- end
101
- end
90
+ class ByCommentCount
91
+ include CouchView::Map
92
+
93
+ def map
94
+ <<-JS
95
+ function(doc){
96
+ if (#{conditions})
97
+ emit(doc.comments.length, null)
98
+ }
99
+ JS
100
+ end
101
+ end
102
102
  ```
103
103
 
104
104
  Notice that we call the "conditions" method inside of our map. This method is mixed into our class by the `CouchView::Map` module. You'll learn how this method allows us to decorate our views with conditions in the next section. For now, let's see what happens if we simply instantiate this class and call the "map" method on it:
105
105
 
106
106
  ```ruby
107
- ByCommentCount.new.map #==>
108
- "
109
- function(doc){
110
- emit(doc.comments.length, null)
111
- }
112
- "
107
+ ByCommentCount.new.map #==>
108
+ "
109
+ function(doc){
110
+ emit(doc.comments.length, null)
111
+ }
112
+ "
113
113
  ```
114
114
 
115
115
  Well that's not very interesting... However, what if we use this map in a model?
116
116
 
117
117
  ```ruby
118
- class Article < CouchRest::Model::Base
119
- include CouchView
120
- property :comments, [String]
121
- map ByCommentCount
122
- end
118
+ class Article < CouchRest::Model::Base
119
+ include CouchView
120
+ property :comments, [String]
121
+ map ByCommentCount
122
+ end
123
123
  ```
124
124
 
125
125
  Now, CouchView will generate a map function on our Article design document that will look like this:
126
126
 
127
127
  ```javascript
128
- function(doc){
129
- if (doc['couchrest-type'] == 'Article')
130
- emit(doc.comments.length, null)
131
- }
128
+ function(doc){
129
+ if (doc['couchrest-type'] == 'Article')
130
+ emit(doc.comments.length, null)
131
+ }
132
132
  ```
133
133
 
134
134
  Similar to before, we can query this index with `map_by_comment_count!` and `count_by_comment_count!`.
@@ -141,6 +141,59 @@ Next, let's imagine that sometimes we'd like to constrain our Article views to p
141
141
  To start, let's define the following condition modules:
142
142
 
143
143
  ```ruby
144
+ module WebExclusive
145
+ def conditions
146
+ "#{super} && doc.web_exclusive == true"
147
+ end
148
+ end
149
+
150
+ module Published
151
+ def conditions
152
+ "#{super} && doc.published == true"
153
+ end
154
+ end
155
+ ```
156
+
157
+ We can then add them into our map definitions thusly:
158
+
159
+ ```ruby
160
+ class Article < CouchRest::Model::Base
161
+ include CouchView
162
+
163
+ property :label
164
+ property :web_exclusive, TrueClass, :default => false
165
+ property :published, TrueClass, :default => false
166
+
167
+ map :label do
168
+ conditions WebExclusive, Published
169
+ end
170
+ end
171
+ ```
172
+
173
+ Now, we can constrain our `map_by_label` query proxy to consider only web exlusive articles, published articles, or both:
174
+
175
+ ```ruby
176
+ Article.map_by_label.published.get!
177
+ #==> published articles ordered by label
178
+
179
+ Article.map_by_label.web_exclusive.get!
180
+ #==> web exclusive articles ordered by label
181
+
182
+ Article.map_by_label.published.web_exclusive.get!
183
+ #==> published, web exclusive articles ordered by label
184
+ ```
185
+
186
+ ### Naming conditions
187
+
188
+ By default, the conditions were named after the module (i.e., "web_exclusive" for WebExclusive, "published" for Published).
189
+
190
+ In a real app, it's likely that you'll end up namespacing your condition modules, in which case, the autogenerated names for your modules won't work.
191
+
192
+ Let's go back to our article example, and imagine that we namespaced our conditions under "Article::Conditions":
193
+
194
+ ```ruby
195
+ class Article
196
+ module Conditions
144
197
  module WebExclusive
145
198
  def conditions
146
199
  "#{super} && doc.web_exclusive == true"
@@ -152,38 +205,37 @@ To start, let's define the following condition modules:
152
205
  "#{super} && doc.published == true"
153
206
  end
154
207
  end
208
+ end
209
+ end
155
210
  ```
156
211
 
157
- We can then add them into our map definitions thusly:
212
+ If we added these conditions to a map, the condition names would not be qualified.
213
+
214
+ If you'd prefer that they be qualified, you'll need to tell `couch_view` what to name them:
158
215
 
159
216
  ```ruby
160
- class Article < CouchRest::Model::Base
161
- include CouchView
217
+ class Article < CouchRest::Model::Base
218
+ include CouchView
162
219
 
163
- property :label
164
- property :web_exclusive, TrueClass, :default => false
165
- property :published, TrueClass, :default => false
220
+ property :label
221
+ property :web_exclusive, TrueClass, :default => false
222
+ property :published, TrueClass, :default => false
166
223
 
167
- map :label do
168
- conditions WebExclusive, Published
169
- end
224
+ map :label do
225
+ conditions do
226
+ filter_by_web_exclusive Conditions::WebExclusive
227
+ filter_by_published Conditions::Published
170
228
  end
229
+ end
230
+ end
171
231
  ```
172
232
 
173
- Now, we can constrain our `map_by_label` query proxy to consider only web exlusive articles, published articles, or both:
233
+ Now you can use these conditions on your proxy:
174
234
 
175
235
  ```ruby
176
- Article.map_by_label.published.get!
177
- #==> published articles ordered by label
178
-
179
- Article.map_by_label.web_exclusive.get!
180
- #==> web exclusive articles ordered by label
181
-
182
- Article.map_by_label.published.web_exclusive.get!
183
- #==> published, web exclusive articles ordered by label
236
+ Article.map_by_label.filter_by_web_exclusive.filter_by_published.each {...}
184
237
  ```
185
238
 
186
-
187
239
  ## Query Proxy
188
240
 
189
241
  CouchView includes a simple query proxy system for building your map/reduce queries.
@@ -191,66 +243,66 @@ CouchView includes a simple query proxy system for building your map/reduce quer
191
243
  Given the following model:
192
244
 
193
245
  ```ruby
194
- class Article < CouchRest::Model::Base
195
- include CouchView
196
- map :label
197
- end
246
+ class Article < CouchRest::Model::Base
247
+ include CouchView
248
+ map :label
249
+ end
198
250
  ```
199
251
 
200
252
  When you call `map_by_label`, you'll recieve a proxy for the query you want to run:
201
253
 
202
254
  ```ruby
203
- proxy = Article.map_by_label
255
+ proxy = Article.map_by_label
204
256
  ```
205
257
 
206
258
  You can now begin modifying your proxy with the standard CouchDB query options. For example, suppose we'd like to limit our result to 10. We can call either the `limit` method, or the `limit!` method. The former will return a new proxy, and leave the original untouched. The latter will modify the proxy it was called on.
207
259
 
208
260
  ```ruby
209
- # generate a new proxy
210
- new_proxy = proxy.limit 10
261
+ # generate a new proxy
262
+ new_proxy = proxy.limit 10
211
263
 
212
- # or update the existing property
213
- proxy.limit!(10)
264
+ # or update the existing property
265
+ proxy.limit!(10)
214
266
  ```
215
267
 
216
268
  Here's the full list of CouchDB query parameters that `CouchView` supports:
217
269
 
218
270
  ```ruby
219
- limit
220
- skip
221
- startkey
222
- endkey
223
- startkey_docid
224
- endkey_docid
225
- stale
226
- descending
227
- group
228
- group_level
229
- reduce
230
- include_docs
231
- update_seq
271
+ limit
272
+ skip
273
+ startkey
274
+ endkey
275
+ startkey_docid
276
+ endkey_docid
277
+ stale
278
+ descending
279
+ group
280
+ group_level
281
+ reduce
282
+ include_docs
283
+ update_seq
232
284
  ```
233
285
 
234
286
  Your query will execute when you call `each` or `get!` on it:
235
287
 
236
288
  ```ruby
237
- Article.map_by_label.startkey!("a").endkey!("b").each do |articles|
238
- # do something with the articles
239
- end
289
+ Article.map_by_label.startkey!("a").endkey!("b").each do |articles|
290
+ # do something with the articles
291
+ end
240
292
 
241
- # or...
293
+ # or...
242
294
 
243
- articles = Article.map_by_label.startkey!("a").endkey!("b").get!
295
+ articles = Article.map_by_label.startkey!("a").endkey!("b").get!
244
296
  ```
245
297
 
246
298
  You can also make your `map_by_label` and `count_by_label` return immediately by adding an `!` onto the end:
247
299
 
248
300
  ```ruby
249
- Article.map_by_label!
250
- #==> [Article<#848283>,...]
301
+ Article.map_by_label!
302
+ #==> [Article<#848283>,...]
251
303
 
252
- Article.count_by_label!
253
- #==> 5
304
+ Article.count_by_label!
305
+ #==> 5
254
306
  ```
255
307
 
256
308
  ## Arbitrary Reduce
@@ -258,26 +310,26 @@ You can also make your `map_by_label` and `count_by_label` return immediately by
258
310
  You can add any arbitrary reduce onto your view by using the `reduce` class method. Just make sure to group it with a map by placing them both within a `couch_view` block:
259
311
 
260
312
  ```ruby
261
- class Article < CouchRest::Model::Base
262
- include CouchView
263
-
264
- property :label
265
-
266
- couch_view do
267
- map :label
268
- reduce <<-JS
269
- function(key, values){
270
- return sum(values)
271
- }
272
- JS
273
- end
274
- end
313
+ class Article < CouchRest::Model::Base
314
+ include CouchView
315
+
316
+ property :label
317
+
318
+ couch_view do
319
+ map :label
320
+ reduce <<-JS
321
+ function(key, values){
322
+ return sum(values)
323
+ }
324
+ JS
325
+ end
326
+ end
275
327
  ```
276
328
 
277
329
  And now you can call it with:
278
330
 
279
331
  ```ruby
280
- Article.reduce_by_label.get!
332
+ Article.reduce_by_label.get!
281
333
  ```
282
334
 
283
335
  Note that you can still call `map_by_label` as well. You can't, however, call `count_by_label`.
@@ -290,18 +342,18 @@ As you've seen, `CouchView` will generate names for your views based on the prop
290
342
  You can override this default name by passing a name to the `couch_view` method:
291
343
 
292
344
  ```ruby
293
- class Article < CouchRest::Model::Base
294
- include CouchView
345
+ class Article < CouchRest::Model::Base
346
+ include CouchView
295
347
 
296
- couch_view :over_label do
297
- map :label
298
- end
299
- end
348
+ couch_view :over_label do
349
+ map :label
350
+ end
351
+ end
300
352
  ```
301
353
 
302
354
  You can now call your view using the `map_over_label` and `count_over_label` methods:
303
355
 
304
356
  ```ruby
305
- Article.map_over_label!
306
- Article.count_over_label!
357
+ Article.map_over_label!
358
+ Article.count_over_label!
307
359
  ```
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: couch_view
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
+ - 1
8
9
  - 0
9
- - 3
10
- version: 0.0.3
10
+ version: 0.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Matt Parker
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-08-18 00:00:00 Z
18
+ date: 2011-08-25 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: couchrest
@@ -101,6 +101,7 @@ extra_rdoc_files: []
101
101
 
102
102
  files:
103
103
  - lib/couch_view/array.rb
104
+ - lib/couch_view/conditions.rb
104
105
  - lib/couch_view/config.rb
105
106
  - lib/couch_view/couch_view.rb
106
107
  - lib/couch_view/count_proxy.rb
@@ -111,6 +112,7 @@ files:
111
112
  - lib/couch_view.rb
112
113
  - readme.markdown
113
114
  - features/couch_view.array.feature
115
+ - features/couch_view.conditions.feature
114
116
  - features/couch_view.config.feature
115
117
  - features/couch_view.count.proxy.feature
116
118
  - features/couch_view.feature
@@ -119,6 +121,7 @@ files:
119
121
  - features/setup/env.rb
120
122
  - features/setup/hooks.rb
121
123
  - features/step_definitions/couch_view.array.rb
124
+ - features/step_definitions/couch_view.conditions.rb
122
125
  - features/step_definitions/couch_view.config.rb
123
126
  - features/step_definitions/couch_view.count.proxy.rb
124
127
  - features/step_definitions/couch_view.map.rb
@@ -159,6 +162,7 @@ specification_version: 3
159
162
  summary: Powerful views for CouchRest::Model::Base
160
163
  test_files:
161
164
  - features/couch_view.array.feature
165
+ - features/couch_view.conditions.feature
162
166
  - features/couch_view.config.feature
163
167
  - features/couch_view.count.proxy.feature
164
168
  - features/couch_view.feature
@@ -167,6 +171,7 @@ test_files:
167
171
  - features/setup/env.rb
168
172
  - features/setup/hooks.rb
169
173
  - features/step_definitions/couch_view.array.rb
174
+ - features/step_definitions/couch_view.conditions.rb
170
175
  - features/step_definitions/couch_view.config.rb
171
176
  - features/step_definitions/couch_view.count.proxy.rb
172
177
  - features/step_definitions/couch_view.map.rb