Permalink
Browse files

Refactored predefined_resource_with into first_or_predefined.

* first_or_predefined accepts query attributes and predefined attributes
  to search for, much like first_or_create.
  • Loading branch information...
1 parent bba4992 commit a00a1b8de599290a52841728da3c7fec573596c8 @postmodern committed Jul 27, 2011
Showing with 52 additions and 20 deletions.
  1. +1 −1 README.md
  2. +32 −17 lib/dm-is-predefined/is/predefined.rb
  3. +19 −2 spec/integration/predefined_spec.rb
View
@@ -44,7 +44,7 @@ A DataMapper plugin for adding predefined resources to Models.
Licence.predefined_resource(:mit)
# => #<Licence: id: 2, name: "MIT">
- License.first_predefined_resource(:name => 'GPL-2')
+ License.first_or_predefined(:name => 'GPL-2')
# => #<License: id: 1, name: "GPL-2", url: "http://www.gnu.org/copyleft/gpl.html">
Licence.gpl2
@@ -151,41 +151,56 @@ def predefined_resource(name)
# Finds or auto-creates the predefined resource which shares the
# given attributes.
#
- # @param [Hash{Symbol => Object}] query
+ # @param [Hash{Symbol => Object}] conditions
+ # Query conditions.
+ #
+ # @param [Hash{Symbol => Object}] attributes
# The attribute names and values that the predefined resource
# should shared.
#
- # @return [DataMapper::Resource]
+ # @return [DataMapper::Resource, nil]
# The predefined resource.
#
+ # @since 0.4.0
+ #
+ # @api public
+ #
+ def first_or_predefined(conditions={},attributes=conditions)
+ if (resource = first(conditions))
+ return resource
+ end
+
+ # if the resource wasn't found, search for matching
+ # predefined attributes
+ attributes = predefined_attributes.values.find do |attrs|
+ attrs.all? do |name,value|
+ attributes.has_key?(name) && (attributes[name] == value)
+ end
+ end
+
+ # create the resource using the predefined attributes
+ create(attributes) if attributes
+ end
+
+ #
# @raise [UnknownResource]
# Could not find a predefined resource that shared all of the
# desired attributes.
#
# @deprecated
- # Will be removed in 1.0.0. Instead, search {#predefined_attributes}
- # directly.
+ # Will be removed in 1.0.0. Use {#first_or_predefined} instead.
#
# @since 0.2.1
#
# @api public
#
def predefined_resource_with(query={})
- if (resource = first(query))
- return resource
+ unless (resource = first_or_predefined(query))
+ # no pre-existing or predefined resource matching the query
+ raise(UnknownResource,"Could not find a predefined resource which shared the given attributes")
end
- # if the resource wasn't found, search for matching
- # predefined attributes
- attributes = predefined_attributes.values.find do |attributes|
- query.all? { |k,v| attributes.has_key?(k) && attributes[k] == v }
- end
-
- # create the resource using the predefined attributes
- return create(attributes) if attributes
-
- # no pre-existing or predefined resource matching the query
- raise(UnknownResource,"Could not find a predefined resource which shared the given attributes")
+ return resource
end
#
@@ -95,13 +95,30 @@
end
end
- describe "predefined_resource_with" do
+ describe "first_or_predefined" do
it "should find resources based on attributes they share" do
- test2 = TestModel.predefined_resource_with(:name => 'test2', :number => 2)
+ test2 = TestModel.first_or_predefined(:name => 'test2', :number => 2)
+
+ test2.name.should == 'test2'
+ end
+
+ it "should allow specifying different query and predefined attributes" do
+ test2 = TestModel.first_or_predefined(
+ {:name.like => '%test2%'},
+ {:name => 'test2', :number => 2}
+ )
test2.name.should == 'test2'
end
+ it "should return nil if no resource shares any attribute values" do
+ resource = TestModel.first_or_predefined(:number => 100, :optional => 'bla')
+
+ resource.should be_nil
+ end
+ end
+
+ describe "predefined_resource_with" do
it "should raise UnknownResource if no resource shares any attribute values" do
lambda {
TestModel.predefined_resource_with(:number => 100, :optional => 'bla')

0 comments on commit a00a1b8

Please sign in to comment.