dm-core 1.1.0.rc2 → 1.1.0.rc3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +1 -8
- data/VERSION +1 -1
- data/dm-core.gemspec +24 -15
- data/lib/dm-core.rb +9 -48
- data/lib/dm-core/adapters.rb +1 -1
- data/lib/dm-core/adapters/abstract_adapter.rb +2 -1
- data/lib/dm-core/associations/many_to_many.rb +3 -3
- data/lib/dm-core/associations/many_to_one.rb +15 -4
- data/lib/dm-core/associations/one_to_many.rb +1 -1
- data/lib/dm-core/associations/relationship.rb +7 -6
- data/lib/dm-core/collection.rb +7 -2
- data/lib/dm-core/core_ext/pathname.rb +0 -14
- data/lib/dm-core/ext/array.rb +41 -0
- data/lib/dm-core/ext/blank.rb +24 -0
- data/lib/dm-core/ext/hash.rb +67 -0
- data/lib/dm-core/ext/module.rb +49 -0
- data/lib/dm-core/ext/object.rb +57 -0
- data/lib/dm-core/ext/singleton_class.rb +8 -0
- data/lib/dm-core/ext/string.rb +24 -0
- data/lib/dm-core/ext/try_dup.rb +12 -0
- data/lib/dm-core/model.rb +2 -1
- data/lib/dm-core/model/property.rb +3 -2
- data/lib/dm-core/property.rb +1 -1
- data/lib/dm-core/property/class.rb +1 -1
- data/lib/dm-core/property/date.rb +3 -3
- data/lib/dm-core/property/date_time.rb +3 -3
- data/lib/dm-core/property/time.rb +3 -3
- data/lib/dm-core/property/typecast/time.rb +2 -2
- data/lib/dm-core/property_set.rb +1 -1
- data/lib/dm-core/query.rb +9 -12
- data/lib/dm-core/resource.rb +2 -2
- data/lib/dm-core/spec/lib/counter_adapter.rb +1 -1
- data/lib/dm-core/spec/lib/spec_helper.rb +1 -1
- data/lib/dm-core/spec/shared/resource_spec.rb +2 -1
- data/lib/dm-core/support/equalizer.rb +1 -1
- data/lib/dm-core/support/hook.rb +0 -15
- data/lib/dm-core/support/inflections.rb +60 -0
- data/lib/dm-core/support/inflector.rb +3 -0
- data/lib/dm-core/support/inflector/inflections.rb +211 -0
- data/lib/dm-core/support/inflector/methods.rb +151 -0
- data/lib/dm-core/support/lazy_array.rb +4 -4
- data/lib/dm-core/support/mash.rb +176 -0
- data/lib/dm-core/support/subject.rb +1 -1
- data/lib/dm-core/version.rb +1 -1
- data/spec/public/model/relationship_spec.rb +2 -1
- data/spec/public/shared/collection_shared_spec.rb +5 -2
- data/spec/public/shared/finder_shared_spec.rb +10 -6
- data/spec/semipublic/adapters/in_memory_adapter_spec.rb +1 -1
- data/spec/semipublic/query_spec.rb +2 -2
- data/spec/semipublic/resource/state/immutable_spec.rb +2 -1
- data/spec/semipublic/resource/state_spec.rb +1 -3
- data/spec/semipublic/shared/resource_state_shared_spec.rb +2 -1
- data/spec/semipublic/shared/subject_shared_spec.rb +1 -1
- data/spec/support/core_ext/hash.rb +10 -0
- data/spec/support/core_ext/inheritable_attributes.rb +46 -0
- data/spec/unit/array_spec.rb +8 -20
- data/spec/unit/blank_spec.rb +62 -0
- data/spec/unit/data_mapper/ordered_set/hash_spec.rb +1 -1
- data/spec/unit/hash_spec.rb +8 -16
- data/spec/unit/lazy_array_spec.rb +3 -14
- data/spec/unit/mash_spec.rb +312 -0
- data/spec/unit/module_spec.rb +15 -15
- data/spec/unit/object_spec.rb +9 -9
- data/spec/unit/try_dup_spec.rb +8 -8
- metadata +32 -39
- data/lib/dm-core/core_ext/array.rb +0 -36
- data/lib/dm-core/core_ext/hash.rb +0 -30
- data/lib/dm-core/core_ext/module.rb +0 -46
- data/lib/dm-core/core_ext/object.rb +0 -31
- data/lib/dm-core/core_ext/string.rb +0 -22
- data/lib/dm-core/core_ext/try_dup.rb +0 -44
@@ -0,0 +1,24 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Ext
|
3
|
+
# Determines whether the specified +value+ is blank.
|
4
|
+
#
|
5
|
+
# An object is blank if it's false, empty, or a whitespace string.
|
6
|
+
# For example, "", " ", +nil+, [], and {} are blank.
|
7
|
+
#
|
8
|
+
# @api semipublic
|
9
|
+
def self.blank?(value)
|
10
|
+
case value
|
11
|
+
when ::NilClass, ::FalseClass
|
12
|
+
true
|
13
|
+
when ::TrueClass, ::Numeric
|
14
|
+
false
|
15
|
+
when ::Array, ::Hash
|
16
|
+
value.empty?
|
17
|
+
when ::String
|
18
|
+
value !~ /\S/
|
19
|
+
else
|
20
|
+
value.nil? || (value.respond_to?(:empty?) && value.empty?)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module DataMapper; module Ext
|
2
|
+
module Hash
|
3
|
+
# Creates a hash with *only* the specified key/value pairs from +hash+.
|
4
|
+
#
|
5
|
+
# @param [Hash] hash The hash from which to pick the key/value pairs.
|
6
|
+
# @param [Array] *keys The hash keys to include.
|
7
|
+
#
|
8
|
+
# @return [Hash] A new hash with only the selected keys.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# hash = { :one => 1, :two => 2, :three => 3 }
|
12
|
+
# Ext::Hash.only(hash, :one, :two) # => { :one => 1, :two => 2 }
|
13
|
+
#
|
14
|
+
# @api semipublic
|
15
|
+
def self.only(hash, *keys)
|
16
|
+
h = {}
|
17
|
+
keys.each {|k| h[k] = hash[k] if hash.has_key?(k) }
|
18
|
+
h
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns a hash that includes everything but the given +keys+.
|
22
|
+
#
|
23
|
+
# @param [Hash] hash The hash from which to pick the key/value pairs.
|
24
|
+
# @param [Array] *keys The hash keys to exclude.
|
25
|
+
#
|
26
|
+
# @return [Hash] A new hash without the specified keys.
|
27
|
+
#
|
28
|
+
# @example
|
29
|
+
# hash = { :one => 1, :two => 2, :three => 3 }
|
30
|
+
# Ext::Hash.except(hash, :one, :two) # => { :three => 3 }
|
31
|
+
#
|
32
|
+
# @api semipublic
|
33
|
+
def self.except(hash, *keys)
|
34
|
+
self.except!(hash.dup, *keys)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Removes the specified +keys+ from the given +hash+.
|
38
|
+
#
|
39
|
+
# @param [Hash] hash The hash to modify.
|
40
|
+
# @param [Array] *keys The hash keys to exclude.
|
41
|
+
#
|
42
|
+
# @return [Hash] +hash+
|
43
|
+
#
|
44
|
+
# @example
|
45
|
+
# hash = { :one => 1, :two => 2, :three => 3 }
|
46
|
+
# Ext::Hash.except!(hash, :one, :two)
|
47
|
+
# hash # => { :three => 3 }
|
48
|
+
#
|
49
|
+
# @api semipublic
|
50
|
+
def self.except!(hash, *keys)
|
51
|
+
keys.each { |key| hash.delete(key) }
|
52
|
+
hash
|
53
|
+
end
|
54
|
+
|
55
|
+
# Converts the specified +hash+ to a {Mash}.
|
56
|
+
#
|
57
|
+
# @param [Hash] hash The hash to convert.
|
58
|
+
# @return [Mash] The {Mash} for the specified +hash+.
|
59
|
+
#
|
60
|
+
# @api semipublic
|
61
|
+
def self.to_mash(hash)
|
62
|
+
h = Mash.new(hash)
|
63
|
+
h.default = hash.default
|
64
|
+
h
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end; end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'dm-core/ext/object'
|
2
|
+
|
3
|
+
module DataMapper; module Ext
|
4
|
+
module Module
|
5
|
+
|
6
|
+
# @api semipublic
|
7
|
+
def self.find_const(mod, const_name)
|
8
|
+
if const_name[0..1] == '::'
|
9
|
+
DataMapper::Ext::Object.full_const_get(const_name[2..-1])
|
10
|
+
else
|
11
|
+
nested_const_lookup(mod, const_name)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
# Doesn't do any caching since constants can change with remove_const
|
18
|
+
def self.nested_const_lookup(mod, const_name)
|
19
|
+
unless mod.equal?(::Object)
|
20
|
+
constants = []
|
21
|
+
|
22
|
+
mod.name.split('::').each do |part|
|
23
|
+
const = constants.last || ::Object
|
24
|
+
constants << const.const_get(part)
|
25
|
+
end
|
26
|
+
|
27
|
+
parts = const_name.split('::')
|
28
|
+
|
29
|
+
# from most to least specific constant, use each as a base and try
|
30
|
+
# to find a constant with the name const_name within them
|
31
|
+
constants.reverse_each do |const|
|
32
|
+
# return the nested constant if available
|
33
|
+
return const if parts.all? do |part|
|
34
|
+
const = if RUBY_VERSION >= '1.9.0'
|
35
|
+
const.const_defined?(part, false) ? const.const_get(part, false) : nil
|
36
|
+
else
|
37
|
+
const.const_defined?(part) ? const.const_get(part) : nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# no relative constant found, fallback to an absolute lookup and
|
44
|
+
# use const_missing if not found
|
45
|
+
DataMapper::Ext::Object.full_const_get(const_name)
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end; end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module DataMapper; module Ext
|
2
|
+
module Object
|
3
|
+
# Returns the value of the specified constant.
|
4
|
+
#
|
5
|
+
# @overload full_const_get(obj, name)
|
6
|
+
# Returns the value of the specified constant in +obj+.
|
7
|
+
# @param [Object] obj The root object used as origin.
|
8
|
+
# @param [String] name The name of the constant to get, e.g. "Merb::Router".
|
9
|
+
#
|
10
|
+
# @overload full_const_get(name)
|
11
|
+
# Returns the value of the fully-qualified constant.
|
12
|
+
# @param [String] name The name of the constant to get, e.g. "Merb::Router".
|
13
|
+
#
|
14
|
+
# @return [Object] The constant corresponding to +name+.
|
15
|
+
#
|
16
|
+
# @api semipublic
|
17
|
+
def self.full_const_get(obj, name = nil)
|
18
|
+
obj, name = ::Object, obj if name.nil?
|
19
|
+
|
20
|
+
list = name.split("::")
|
21
|
+
list.shift if DataMapper::Ext.blank?(list.first)
|
22
|
+
list.each do |x|
|
23
|
+
# This is required because const_get tries to look for constants in the
|
24
|
+
# ancestor chain, but we only want constants that are HERE
|
25
|
+
obj = obj.const_defined?(x) ? obj.const_get(x) : obj.const_missing(x)
|
26
|
+
end
|
27
|
+
obj
|
28
|
+
end
|
29
|
+
|
30
|
+
# Sets the specified constant to the given +value+.
|
31
|
+
#
|
32
|
+
# @overload full_const_set(obj, name)
|
33
|
+
# Sets the specified constant in +obj+ to the given +value+.
|
34
|
+
# @param [Object] obj The root object used as origin.
|
35
|
+
# @param [String] name The name of the constant to set, e.g. "Merb::Router".
|
36
|
+
# @param [Object] value The value to assign to the constant.
|
37
|
+
#
|
38
|
+
# @overload full_const_set(name)
|
39
|
+
# Sets the fully-qualified constant to the given +value+.
|
40
|
+
# @param [String] name The name of the constant to set, e.g. "Merb::Router".
|
41
|
+
# @param [Object] value The value to assign to the constant.
|
42
|
+
#
|
43
|
+
# @return [Object] The constant corresponding to +name+.
|
44
|
+
#
|
45
|
+
# @api semipublic
|
46
|
+
def self.full_const_set(obj, name, value = nil)
|
47
|
+
obj, name, value = ::Object, obj, name if value.nil?
|
48
|
+
|
49
|
+
list = name.split("::")
|
50
|
+
toplevel = DataMapper::Ext.blank?(list.first)
|
51
|
+
list.shift if toplevel
|
52
|
+
last = list.pop
|
53
|
+
obj = list.empty? ? ::Object : DataMapper::Ext::Object.full_const_get(list.join("::"))
|
54
|
+
obj.const_set(last, value) if obj && !obj.const_defined?(last)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end; end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module DataMapper; module Ext
|
2
|
+
module String
|
3
|
+
# Replace sequences of whitespace (including newlines) with either
|
4
|
+
# a single space or remove them entirely (according to param _spaced_).
|
5
|
+
#
|
6
|
+
# compress_lines(<<QUERY)
|
7
|
+
# SELECT name
|
8
|
+
# FROM users
|
9
|
+
# QUERY => "SELECT name FROM users"
|
10
|
+
#
|
11
|
+
# @param [String] string
|
12
|
+
# The input string.
|
13
|
+
#
|
14
|
+
# @param [TrueClass, FalseClass] spaced (default=true)
|
15
|
+
# Determines whether returned string has whitespace collapsed or removed.
|
16
|
+
#
|
17
|
+
# @return [String] The input string with whitespace (including newlines) replaced.
|
18
|
+
#
|
19
|
+
# @api semipublic
|
20
|
+
def self.compress_lines(string, spaced = true)
|
21
|
+
string.split($/).map { |line| line.strip }.join(spaced ? ' ' : '')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end; end
|
data/lib/dm-core/model.rb
CHANGED
@@ -564,7 +564,8 @@ module DataMapper
|
|
564
564
|
discriminator = properties(repository_name).discriminator
|
565
565
|
no_reload = !query.reload?
|
566
566
|
|
567
|
-
field_map = fields.map { |property| [ property, property.field ] }
|
567
|
+
field_map = fields.map { |property| [ property, property.field ] }
|
568
|
+
field_map = DataMapper::Ext::Array.to_hash(field_map)
|
568
569
|
|
569
570
|
records.map do |record|
|
570
571
|
identity_map = nil
|
@@ -65,7 +65,7 @@ module DataMapper
|
|
65
65
|
# Add property to the other mappings as well if this is for the default
|
66
66
|
# repository.
|
67
67
|
if repository_name == default_repository_name
|
68
|
-
|
68
|
+
DataMapper::Ext::Hash.except(@properties, default_repository_name).each do |other_repository_name, properties|
|
69
69
|
next if properties.named?(name)
|
70
70
|
|
71
71
|
# make sure the property is created within the correct repository scope
|
@@ -175,7 +175,8 @@ module DataMapper
|
|
175
175
|
|
176
176
|
# @api private
|
177
177
|
def key_conditions(repository, key)
|
178
|
-
self.key(repository.name).zip(key.nil? ? [] : key)
|
178
|
+
conditions = self.key(repository.name).zip(key.nil? ? [] : key)
|
179
|
+
DataMapper::Ext::Array.to_hash(conditions)
|
179
180
|
end
|
180
181
|
|
181
182
|
private
|
data/lib/dm-core/property.rb
CHANGED
@@ -764,7 +764,7 @@ module DataMapper
|
|
764
764
|
@instance_variable_name = "@#{@name}".freeze
|
765
765
|
|
766
766
|
@primitive = self.class.primitive
|
767
|
-
@field = @options[:field].freeze
|
767
|
+
@field = @options[:field].freeze unless @options[:field].nil?
|
768
768
|
@default = @options[:default]
|
769
769
|
|
770
770
|
@serial = @options.fetch(:serial, false)
|
@@ -11,7 +11,7 @@ module DataMapper
|
|
11
11
|
# Typecasts an arbitrary value to a Date
|
12
12
|
# Handles both Hashes and Date instances.
|
13
13
|
#
|
14
|
-
# @param [#to_mash, #to_s] value
|
14
|
+
# @param [Hash, #to_mash, #to_s] value
|
15
15
|
# value to be typecast
|
16
16
|
#
|
17
17
|
# @return [Date]
|
@@ -21,7 +21,7 @@ module DataMapper
|
|
21
21
|
def typecast_to_primitive(value)
|
22
22
|
if value.respond_to?(:to_date)
|
23
23
|
value.to_date
|
24
|
-
elsif value.respond_to?(:to_mash)
|
24
|
+
elsif value.is_a?(::Hash) || value.respond_to?(:to_mash)
|
25
25
|
typecast_hash_to_date(value)
|
26
26
|
else
|
27
27
|
::Date.parse(value.to_s)
|
@@ -32,7 +32,7 @@ module DataMapper
|
|
32
32
|
|
33
33
|
# Creates a Date instance from a Hash with keys :year, :month, :day
|
34
34
|
#
|
35
|
-
# @param [#to_mash] value
|
35
|
+
# @param [Hash, #to_mash] value
|
36
36
|
# value to be typecast
|
37
37
|
#
|
38
38
|
# @return [Date]
|
@@ -11,7 +11,7 @@ module DataMapper
|
|
11
11
|
# Typecasts an arbitrary value to a DateTime.
|
12
12
|
# Handles both Hashes and DateTime instances.
|
13
13
|
#
|
14
|
-
# @param [#to_mash, #to_s] value
|
14
|
+
# @param [Hash, #to_mash, #to_s] value
|
15
15
|
# value to be typecast
|
16
16
|
#
|
17
17
|
# @return [DateTime]
|
@@ -19,7 +19,7 @@ module DataMapper
|
|
19
19
|
#
|
20
20
|
# @api private
|
21
21
|
def typecast_to_primitive(value)
|
22
|
-
if value.respond_to?(:to_mash)
|
22
|
+
if value.is_a?(::Hash) || value.respond_to?(:to_mash)
|
23
23
|
typecast_hash_to_datetime(value)
|
24
24
|
else
|
25
25
|
::DateTime.parse(value.to_s)
|
@@ -31,7 +31,7 @@ module DataMapper
|
|
31
31
|
# Creates a DateTime instance from a Hash with keys :year, :month, :day,
|
32
32
|
# :hour, :min, :sec
|
33
33
|
#
|
34
|
-
# @param [#to_mash] value
|
34
|
+
# @param [Hash, #to_mash] value
|
35
35
|
# value to be typecast
|
36
36
|
#
|
37
37
|
# @return [DateTime]
|
@@ -11,7 +11,7 @@ module DataMapper
|
|
11
11
|
# Typecasts an arbitrary value to a Time
|
12
12
|
# Handles both Hashes and Time instances.
|
13
13
|
#
|
14
|
-
# @param [#to_mash, #to_s] value
|
14
|
+
# @param [Hash, #to_mash, #to_s] value
|
15
15
|
# value to be typecast
|
16
16
|
#
|
17
17
|
# @return [Time]
|
@@ -21,7 +21,7 @@ module DataMapper
|
|
21
21
|
def typecast_to_primitive(value)
|
22
22
|
if value.respond_to?(:to_time)
|
23
23
|
value.to_time
|
24
|
-
elsif value.respond_to?(:to_mash)
|
24
|
+
elsif value.is_a?(::Hash) || value.respond_to?(:to_mash)
|
25
25
|
typecast_hash_to_time(value)
|
26
26
|
else
|
27
27
|
::Time.parse(value.to_s)
|
@@ -33,7 +33,7 @@ module DataMapper
|
|
33
33
|
# Creates a Time instance from a Hash with keys :year, :month, :day,
|
34
34
|
# :hour, :min, :sec
|
35
35
|
#
|
36
|
-
# @param [#to_mash] value
|
36
|
+
# @param [Hash, #to_mash] value
|
37
37
|
# value to be typecast
|
38
38
|
#
|
39
39
|
# @return [Time]
|
@@ -7,7 +7,7 @@ module DataMapper
|
|
7
7
|
# Extracts the given args from the hash. If a value does not exist, it
|
8
8
|
# uses the value of Time.now.
|
9
9
|
#
|
10
|
-
# @param [#to_mash] value
|
10
|
+
# @param [Hash, #to_mash] value
|
11
11
|
# value to extract time args from
|
12
12
|
#
|
13
13
|
# @return [Array]
|
@@ -15,7 +15,7 @@ module DataMapper
|
|
15
15
|
#
|
16
16
|
# @api private
|
17
17
|
def extract_time(value)
|
18
|
-
mash = value.to_mash
|
18
|
+
mash = value.respond_to?(:to_mash) ? value.to_mash : DataMapper::Ext::Hash.to_mash(value)
|
19
19
|
now = ::Time.now
|
20
20
|
|
21
21
|
[ :year, :month, :day, :hour, :min, :sec ].map do |segment|
|
data/lib/dm-core/property_set.rb
CHANGED
data/lib/dm-core/query.rb
CHANGED
@@ -362,12 +362,12 @@ module DataMapper
|
|
362
362
|
@options = @options.merge(other_options).freeze
|
363
363
|
assert_valid_options(@options)
|
364
364
|
|
365
|
-
normalize =
|
366
|
-
instance_variable_set("@#{attribute}",
|
365
|
+
normalize = DataMapper::Ext::Hash.only(other_options, *OPTIONS - [ :conditions ]).map do |attribute, value|
|
366
|
+
instance_variable_set("@#{attribute}", DataMapper::Ext.try_dup(value))
|
367
367
|
attribute
|
368
368
|
end
|
369
369
|
|
370
|
-
merge_conditions([
|
370
|
+
merge_conditions([ DataMapper::Ext::Hash.except(other_options, *OPTIONS), other_options[:conditions] ])
|
371
371
|
normalize_options(normalize | [ :links, :unique ])
|
372
372
|
|
373
373
|
self
|
@@ -689,7 +689,7 @@ module DataMapper
|
|
689
689
|
#
|
690
690
|
# @api private
|
691
691
|
def to_relative_hash
|
692
|
-
|
692
|
+
DataMapper::Ext::Hash.only(to_hash, :fields, :order, :unique, :add_reversed, :reload)
|
693
693
|
end
|
694
694
|
|
695
695
|
private
|
@@ -737,7 +737,7 @@ module DataMapper
|
|
737
737
|
@reload = @options.fetch :reload, false
|
738
738
|
@raw = false
|
739
739
|
|
740
|
-
merge_conditions([
|
740
|
+
merge_conditions([ DataMapper::Ext::Hash.except(@options, *OPTIONS), @options[:conditions] ])
|
741
741
|
normalize_options
|
742
742
|
end
|
743
743
|
|
@@ -748,7 +748,7 @@ module DataMapper
|
|
748
748
|
@fields = @fields.dup
|
749
749
|
@links = @links.dup
|
750
750
|
@conditions = @conditions.dup
|
751
|
-
@order = @order
|
751
|
+
@order = DataMapper::Ext.try_dup(@order)
|
752
752
|
end
|
753
753
|
|
754
754
|
# Validate the options
|
@@ -855,12 +855,9 @@ module DataMapper
|
|
855
855
|
when Symbol, ::String
|
856
856
|
original = subject
|
857
857
|
subject = subject.to_s
|
858
|
+
name = subject[0, subject.index('.') || subject.length]
|
858
859
|
|
859
|
-
|
860
|
-
unless @relationships.named?(subject[0, subject.index('.')])
|
861
|
-
raise ArgumentError, "condition #{original.inspect} does not map to a relationship in #{model}"
|
862
|
-
end
|
863
|
-
elsif !@properties.named?(subject) && !@relationships.named?(subject)
|
860
|
+
unless @properties.named?(name) || @relationships.named?(name)
|
864
861
|
raise ArgumentError, "condition #{original.inspect} does not map to a property or relationship in #{model}"
|
865
862
|
end
|
866
863
|
|
@@ -899,7 +896,7 @@ module DataMapper
|
|
899
896
|
|
900
897
|
first_condition = conditions.first
|
901
898
|
|
902
|
-
unless first_condition.kind_of?(String) && !
|
899
|
+
unless first_condition.kind_of?(String) && !DataMapper::Ext.blank?(first_condition)
|
903
900
|
raise ArgumentError, '+options[:conditions]+ should have a statement for the first entry'
|
904
901
|
end
|
905
902
|
end
|