Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Class methods to find by index for #228

  • Loading branch information...
commit 98324800cef140f1728c249e0fc197d028318566 1 parent 79e6717
@jcoyne authored
View
12 lib/ripple/indexes.rb
@@ -63,10 +63,22 @@ def indexes_for_persistence(prefix = '')
# Modifies the persistence chain to set indexes on the internal
# {Riak::RObject} before saving.
module DocumentMethods
+ extend ActiveSupport::Concern
def update_robject
robject.indexes = indexes_for_persistence
super
end
+
+ module ClassMethods
+ # Search for a document using an indexed column
+ # @param [Symbol] name of the index
+ # @param [String, Integer, Range] query to search for
+ def find_by_index(index_name, query)
+ idx = self.indexes[index_name]
+ raise ArgumentError, t('index_undefined', :property => index_name, :type => self.name) if idx.nil?
+ self.find(Ripple.client.get_index(self.bucket.name, idx.index_key, query))
+ end
+ end
end
end
View
1  lib/ripple/locale/en.yml
@@ -11,6 +11,7 @@ en:
one_key: "Couldn't find document with key: %{key}"
many_keys: "Couldn't find documents with keys: %{keys}"
index_type_unknown: "Cannot determine index type for property '%{property}' of type '%{type}'."
+ index_undefined: "No index has been defined for property '%{property}' of type '%{type}'."
invalid_association_value: "Invalid value %{value} for association %{name} of type %{klass} on %{owner}"
many_association_validation_error: "are invalid (%{association_errors})"
many_key_association: "You cannot use a many association using :key"
View
28 spec/ripple/indexes_spec.rb
@@ -57,6 +57,34 @@
subject.indexes_for_persistence['addresses_street_bin'].should == Set["10 Main St", "100 W 10th Avenue"]
end
end
+
+ context "finding documents by an index" do
+ before(:all) do
+ Indexer.destroy_all
+ @bob = Indexer.create(:name => "Bob", :age => 28)
+ @sally = Indexer.create(:name => "Sally", :age => 28)
+ @mary = Indexer.create(:name => "Mary", :age => 25)
+ end
+ after(:all) { Indexer.destroy_all }
+
+ it "should find one" do
+ Ripple.client.stub(:get_index).with('indexers', 'name_bin', 'Bob').and_return([@bob.key])
+ Indexer.find_by_index(:name, 'Bob').should == [@bob]
+ end
+ it "should find many" do
+ Ripple.client.stub(:get_index).with('indexers', 'age_int', 28).and_return([@bob.key, @sally.key])
+ result = Indexer.find_by_index(:age, 28)
+ result.should include(@bob, @sally)
+ result.should_not include(@mary)
+ end
+ it "should find none" do
+ Ripple.client.stub(:get_index).with('indexers', 'age_int', 30).and_return([])
+ Indexer.find_by_index(:age, 30).should == []
+ end
+ it "should raise an error when the requested index doesn't exist" do
+ lambda {Indexer.find_by_index(:hair, 'blonde')}.should raise_error( ArgumentError, "No index has been defined for property 'hair' of type 'Indexer'.")
+ end
+ end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.