Skip to content

Commit

Permalink
added conditions to views
Browse files Browse the repository at this point in the history
  • Loading branch information
langalex committed Dec 15, 2009
1 parent 84329eb commit e032efe
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 13 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1 +1,2 @@
couch_potato_js_runner.js
pkg
3 changes: 3 additions & 0 deletions CHANGES.md
@@ -1,5 +1,8 @@
## Changes

### 0.2.19
* added conditions to views (langalex)

### 0.2.18
* set Fixnum property to nil when given a blank string (langalex)

Expand Down
4 changes: 3 additions & 1 deletion CREDITS
@@ -1,4 +1,6 @@
Parts of this are taken or inspired by Geoffrey Grosenbach's travel_app which is part of his CouchDB screencast.

Jan Lehnardt - got me started on doing this.
Brian Candler - contributed performance patches
Brian Candler - contributed performance patches

see CHANGES.md for all the committers
8 changes: 8 additions & 0 deletions README.md
Expand Up @@ -197,6 +197,14 @@ Composite keys are also possible:
view :all, :key => [:created_at, :name]
end

You can also pass conditions as a JavaScript string:

class User
property :name

view :completed, :key => :name, :conditions => 'doc.completed = true'
end

The creation of views is based on view specification classes (see [CouchPotato::View::BaseViewSpec](http://rdoc.info/rdoc/langalex/couch_potato/blob/e8f0069e5529ad08a1bd1f02637ea8f1d6d0ab5b/CouchPotato/View/BaseViewSpec.html) and its descendants for more detailed documentation). The above code uses the ModelViewSpec class which is used to find models by their properties. For more sophisticated searches you can use other view specifications (either use the built-in or provide your own) by passing a type parameter:

If you have larger structures and you only want to load some attributes you can use the PropertiesViewSpec (the full class name is automatically derived):
Expand Down
24 changes: 19 additions & 5 deletions lib/couch_potato/view/model_view_spec.rb
Expand Up @@ -5,6 +5,9 @@ module View
#
# example:
# view :my_view, :key => :name
#
# in addition you can pass in conditions as a javascript string
# view :my_view_only_completed, :key => :name, :conditions => 'doc.completed = true'
class ModelViewSpec < BaseViewSpec

def view_parameters
Expand All @@ -17,11 +20,9 @@ def view_parameters
end

def map_function
"function(doc) {
if(doc.#{JSON.create_id} && doc.#{JSON.create_id} == '#{@klass.name}') {
emit(#{formatted_key(key)}, null);
}
}"
map_body do
"emit(#{formatted_key(key)}, null);"
end
end

def reduce_function
Expand All @@ -40,6 +41,19 @@ def process_results(results)

private

def map_body(&block)
"function(doc) {
if(doc.#{JSON.create_id} && doc.#{JSON.create_id} == '#{@klass.name}'#{conditions_js}) {
" + yield + "
}
}"

end

def conditions_js
" && (#{options[:conditions]})" if options[:conditions]
end

def count?
view_parameters[:reduce]
end
Expand Down
10 changes: 3 additions & 7 deletions lib/couch_potato/view/properties_view_spec.rb
Expand Up @@ -6,11 +6,9 @@ module View
# view :my_view, :key => :name, :properties => [:name, :author], :type => :properties
class PropertiesViewSpec < ModelViewSpec
def map_function
"function(doc) {
if(doc.#{JSON.create_id} && doc.#{JSON.create_id} == '#{@klass.name}') {
emit(#{formatted_key(key)}, #{properties_for_map(properties)});
}
}"
map_body do
"emit(#{formatted_key(key)}, #{properties_for_map(properties)});"
end
end

def process_results(results)
Expand All @@ -32,8 +30,6 @@ def properties
def properties_for_map(properties)
'{' + properties.map{|p| "#{p}: doc.#{p}"}.join(', ') + '}'
end


end
end
end
13 changes: 13 additions & 0 deletions spec/unit/model_view_spec_spec.rb
@@ -0,0 +1,13 @@
require File.dirname(__FILE__) + '/../spec_helper'

describe CouchPotato::View::ModelViewSpec, 'map_function' do
it "should include conditions" do
spec = CouchPotato::View::ModelViewSpec.new Object, 'all', {:conditions => 'doc.closed = true'}, {}
spec.map_function.should include('if(doc.ruby_class && doc.ruby_class == \'Object\' && (doc.closed = true))')
end

it "should not include conditions when they are nil" do
spec = CouchPotato::View::ModelViewSpec.new Object, 'all', {}, {}
spec.map_function.should include('if(doc.ruby_class && doc.ruby_class == \'Object\')')
end
end

0 comments on commit e032efe

Please sign in to comment.