nobrainer 0.20.0 → 0.22.0

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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/lib/no_brainer/autoload.rb +0 -5
  3. data/lib/no_brainer/config.rb +14 -9
  4. data/lib/no_brainer/connection.rb +1 -3
  5. data/lib/no_brainer/criteria/aggregate.rb +2 -2
  6. data/lib/no_brainer/criteria/cache.rb +8 -3
  7. data/lib/no_brainer/criteria/core.rb +1 -5
  8. data/lib/no_brainer/criteria/delete.rb +1 -1
  9. data/lib/no_brainer/criteria/eager_load.rb +51 -0
  10. data/lib/no_brainer/criteria/find.rb +27 -0
  11. data/lib/no_brainer/criteria/order_by.rb +1 -1
  12. data/lib/no_brainer/criteria/scope.rb +3 -10
  13. data/lib/no_brainer/criteria/update.rb +8 -6
  14. data/lib/no_brainer/criteria/where.rb +50 -13
  15. data/lib/no_brainer/criteria.rb +3 -2
  16. data/lib/no_brainer/document/aliases.rb +0 -8
  17. data/lib/no_brainer/document/association/belongs_to.rb +6 -2
  18. data/lib/no_brainer/document/association/core.rb +5 -4
  19. data/lib/no_brainer/document/association/eager_loader.rb +7 -8
  20. data/lib/no_brainer/document/association/has_many.rb +22 -8
  21. data/lib/no_brainer/document/association/has_many_through.rb +12 -3
  22. data/lib/no_brainer/document/atomic_ops.rb +63 -61
  23. data/lib/no_brainer/document/attributes.rb +11 -3
  24. data/lib/no_brainer/document/core.rb +5 -2
  25. data/lib/no_brainer/document/criteria.rb +14 -17
  26. data/lib/no_brainer/document/dirty.rb +11 -16
  27. data/lib/no_brainer/document/index/meta_store.rb +1 -1
  28. data/lib/no_brainer/document/index.rb +0 -6
  29. data/lib/no_brainer/document/persistance.rb +13 -3
  30. data/lib/no_brainer/document/store_in.rb +2 -2
  31. data/lib/no_brainer/document/types/binary.rb +2 -6
  32. data/lib/no_brainer/document/types/boolean.rb +2 -3
  33. data/lib/no_brainer/document/types/date.rb +2 -2
  34. data/lib/no_brainer/document/types/float.rb +2 -2
  35. data/lib/no_brainer/document/types/geo.rb +1 -0
  36. data/lib/no_brainer/document/types/integer.rb +2 -2
  37. data/lib/no_brainer/document/types/set.rb +2 -2
  38. data/lib/no_brainer/document/types/string.rb +5 -2
  39. data/lib/no_brainer/document/types/symbol.rb +2 -2
  40. data/lib/no_brainer/document/types/text.rb +18 -0
  41. data/lib/no_brainer/document/types/time.rb +2 -2
  42. data/lib/no_brainer/document/types.rb +13 -12
  43. data/lib/no_brainer/document/validation/not_null.rb +15 -0
  44. data/lib/no_brainer/document/{uniqueness.rb → validation/uniqueness.rb} +11 -10
  45. data/lib/no_brainer/document/validation.rb +35 -6
  46. data/lib/no_brainer/document.rb +2 -2
  47. data/lib/no_brainer/error.rb +20 -23
  48. data/lib/no_brainer/locale/en.yml +1 -0
  49. data/lib/no_brainer/lock.rb +114 -0
  50. data/lib/no_brainer/query_runner/database_on_demand.rb +0 -1
  51. data/lib/no_brainer/query_runner/missing_index.rb +1 -1
  52. data/lib/no_brainer/query_runner/run_options.rb +0 -3
  53. data/lib/no_brainer/query_runner/table_on_demand.rb +2 -3
  54. data/lib/no_brainer/rql.rb +0 -4
  55. data/lib/nobrainer.rb +1 -1
  56. metadata +9 -4
  57. data/lib/no_brainer/criteria/preload.rb +0 -44
@@ -2,7 +2,7 @@ class NoBrainer::Document::Association::HasManyThrough
2
2
  include NoBrainer::Document::Association::Core
3
3
 
4
4
  class Metadata
5
- VALID_OPTIONS = [:through]
5
+ VALID_OPTIONS = [:through, :scope]
6
6
  include NoBrainer::Document::Association::Core::Metadata
7
7
 
8
8
  def through_association_name
@@ -14,10 +14,18 @@ class NoBrainer::Document::Association::HasManyThrough
14
14
  raise "#{through_association_name} association not found"
15
15
  end
16
16
 
17
- def eager_load(docs, criteria=nil)
17
+ def eager_load(docs, additional_criteria=nil)
18
+ criteria = target_model.instance_exec(&options[:scope]) if options[:scope]
19
+ criteria = criteria ? criteria.merge(additional_criteria) : additional_criteria if additional_criteria
18
20
  NoBrainer::Document::Association::EagerLoader.new
19
21
  .eager_load_association(through_association.eager_load(docs), target_name, criteria)
20
22
  end
23
+
24
+ def target_model
25
+ meta = through_association.target_model.association_metadata
26
+ association = meta[target_name.to_sym] || meta[target_name.to_s.singularize.to_sym]
27
+ association.target_model
28
+ end
21
29
  end
22
30
 
23
31
  def read
@@ -26,6 +34,7 @@ class NoBrainer::Document::Association::HasManyThrough
26
34
  end
27
35
 
28
36
  def write(new_children)
29
- raise "You can't assign #{target_name}"
37
+ raise "You can't assign `#{target_name}'. " \
38
+ "Instead, you must modify delete and create `#{target_model}' manually."
30
39
  end
31
40
  end
@@ -2,22 +2,38 @@ module NoBrainer::Document::AtomicOps
2
2
  extend ActiveSupport::Concern
3
3
 
4
4
  class PendingAtomic
5
+ attr_accessor :type
6
+
5
7
  def self._new(instance, field, value, is_user_value)
6
- case value
7
- when Array then PendingAtomicArray
8
- when Set then PendingAtomicSet
8
+ type = instance.class.fields[field.to_sym].try(:[], :type)
9
+ type ||= value.class unless value.nil?
10
+
11
+ case
12
+ when type == Array then PendingAtomicArray
13
+ when type == Set then PendingAtomicSet
9
14
  else self
10
- end.new(instance, field, value, is_user_value)
15
+ end.new(instance, field, value, is_user_value, type)
11
16
  end
12
17
 
13
- def initialize(instance, field, value, is_user_value)
18
+ def initialize(instance, field, value, is_user_value, type)
14
19
  @instance = instance
15
20
  @field = field.to_s
16
21
  @value = value
17
22
  @is_user_value = is_user_value
23
+ @type = type
18
24
  @ops = []
19
25
  end
20
26
 
27
+ def default_value
28
+ case
29
+ when @type == Array then []
30
+ when @type == Set then []
31
+ when @type == Integer then 0
32
+ when @type == Float then 0.0
33
+ when @type == String then ""
34
+ end
35
+ end
36
+
21
37
  def initialize_copy(other)
22
38
  super
23
39
  @ops = @ops.dup
@@ -29,6 +45,11 @@ module NoBrainer::Document::AtomicOps
29
45
  alias_method :inspect, :to_s
30
46
 
31
47
  def method_missing(method, *a, &b)
48
+ if method == :<<
49
+ method = :append
50
+ modify_source!
51
+ end
52
+
32
53
  @ops << [method, a, b]
33
54
  self
34
55
  end
@@ -36,11 +57,10 @@ module NoBrainer::Document::AtomicOps
36
57
  def compile_rql_value(rql_doc)
37
58
  field = @instance.class.lookup_field_alias(@field)
38
59
  value = @is_user_value ? RethinkDB::RQL.new.expr(@value) : rql_doc[field]
60
+ value = value.default(default_value) if default_value
39
61
  @ops.reduce(value) { |v, (method, a, b)| v.__send__(method, *a, &b) }
40
62
  end
41
- end
42
63
 
43
- class PendingAtomicContainer < PendingAtomic
44
64
  def modify_source!
45
65
  unless @instance._is_attribute_touched?(@field)
46
66
  @instance.write_attribute(@field, self)
@@ -48,56 +68,59 @@ module NoBrainer::Document::AtomicOps
48
68
  end
49
69
  end
50
70
 
51
- class PendingAtomicArray < PendingAtomicContainer
52
- def -(value)
53
- @ops << [:difference, [value.to_a]]
71
+ class PendingAtomicContainer < PendingAtomic
72
+ def &(value)
73
+ @ops << [:set_intersection, [value.to_a]]
54
74
  self
55
75
  end
56
- def difference(v); self - v; end
76
+
77
+ def |(value)
78
+ @ops << [:set_union, [value.to_a]]
79
+ self
80
+ end
81
+
82
+ def add(v); self + v; end
83
+ def difference(v); self - v; end
84
+ def intersection(v); self & v; end
85
+ def union(v); self | v; end
57
86
 
58
87
  def delete(value)
59
88
  difference([value])
60
89
  end
90
+ end
61
91
 
62
- def +(value)
63
- @ops << [:+, [value.to_a]]
92
+ class PendingAtomicSet < PendingAtomicContainer
93
+ def <<(value)
94
+ @ops << [:set_union, [[value]]]
95
+ modify_source!
64
96
  self
65
97
  end
66
- def add(v); self + v; end
67
98
 
68
- def &(value)
69
- @ops << [:set_intersection, [value.to_a]]
99
+ def +(value)
100
+ @ops << [:set_union, [value.to_a]]
70
101
  self
71
102
  end
72
- def intersection(v); self & v; end
73
103
 
74
- def |(value)
75
- @ops << [:set_union, [value.to_a]]
104
+ def -(value)
105
+ @ops << [:set_difference, [value.to_a]]
76
106
  self
77
107
  end
78
- def union(v); self | v; end
108
+ end
79
109
 
110
+ class PendingAtomicArray < PendingAtomicContainer
80
111
  def <<(value)
81
112
  @ops << [:append, [value]]
82
113
  modify_source!
83
114
  self
84
115
  end
85
- end
86
-
87
- class PendingAtomicSet < PendingAtomicContainer
88
- def -(value)
89
- @ops << [:set_difference, [value.to_a]]
90
- self
91
- end
92
116
 
93
117
  def +(value)
94
- @ops << [:set_union, [value.to_a]]
118
+ @ops << [:+, [value.to_a]]
95
119
  self
96
120
  end
97
121
 
98
- def <<(value)
99
- @ops << [:set_union, [[value]]]
100
- modify_source!
122
+ def -(value)
123
+ @ops << [:difference, [value.to_a]]
101
124
  self
102
125
  end
103
126
  end
@@ -108,6 +131,9 @@ module NoBrainer::Document::AtomicOps
108
131
  end
109
132
 
110
133
  def _touch_attribute(name)
134
+ # The difference with dirty tracking and this is that dirty tracking does
135
+ # not take into account fields that are set with their old value, whereas the
136
+ # touched attribute does.
111
137
  @_touched_attributes << name.to_s
112
138
  end
113
139
 
@@ -142,12 +168,12 @@ module NoBrainer::Document::AtomicOps
142
168
  def _read_attribute(name)
143
169
  ensure_exclusive_atomic!
144
170
  value = super
171
+ return value unless in_atomic?
145
172
 
146
- case [in_atomic?, value.is_a?(PendingAtomic)]
147
- when [true, false] then PendingAtomic._new(self, name, value, _is_attribute_touched?(name))
148
- when [false, true] then raise NoBrainer::Error::CannotReadAtomic.new(self, name, value)
149
- when [true, true] then value.is_a?(PendingAtomicContainer) ? value : value.dup
150
- when [false, false] then value
173
+ case value
174
+ when PendingAtomicContainer then value
175
+ when PendingAtomic then value.dup
176
+ else PendingAtomic._new(self, name, value, _is_attribute_touched?(name))
151
177
  end
152
178
  end
153
179
 
@@ -174,39 +200,15 @@ module NoBrainer::Document::AtomicOps
174
200
  if saved
175
201
  @_attributes.each do |attr, value|
176
202
  next unless value.is_a?(PendingAtomic)
177
- @_attributes[attr] = value.class.new(self, attr, nil, false)
203
+ @_attributes[attr] = value.class.new(self, attr, nil, false, value.type)
178
204
  end
179
205
  end
180
206
  end
181
207
  end
182
208
 
183
- def read_attribute_for_change(attr)
184
- super
185
- rescue NoBrainer::Error::CannotReadAtomic => e
186
- e.value
187
- end
188
-
189
- def read_attribute_for_validation(attr)
190
- super
191
- rescue NoBrainer::Error::CannotReadAtomic => e
192
- e.value
193
- end
194
-
195
209
  module ClassMethods
196
210
  def persistable_value(k, v, options={})
197
211
  v.is_a?(PendingAtomic) ? v.compile_rql_value(options[:rql_doc]) : super
198
212
  end
199
213
  end
200
214
  end
201
-
202
- class ActiveModel::EachValidator
203
- # XXX Monkey Patching :(
204
- def validate(record)
205
- attributes.each do |attribute|
206
- value = record.read_attribute_for_validation(attribute)
207
- next if value.is_a?(NoBrainer::Document::AtomicOps::PendingAtomic) # <--- This is the added line
208
- next if (value.nil? && options[:allow_nil]) || (value.blank? && options[:allow_blank])
209
- validate_each(record, attribute, value)
210
- end
211
- end
212
- end
@@ -1,9 +1,10 @@
1
1
  module NoBrainer::Document::Attributes
2
2
  VALID_FIELD_OPTIONS = [:index, :default, :type, :readonly, :primary_key, :lazy_fetch, :store_as,
3
- :validates, :required, :unique, :uniq, :format, :in]
3
+ :validates, :required, :unique, :uniq, :format, :in, :length, :min_length, :max_length]
4
4
  RESERVED_FIELD_NAMES = [:index, :default, :and, :or, :selector, :associations, :pk_value] \
5
5
  + NoBrainer::Criteria::Where::OPERATORS
6
6
  extend ActiveSupport::Concern
7
+ include ActiveModel::ForbiddenAttributesProtection
7
8
 
8
9
  included do
9
10
  singleton_class.send(:attr_accessor, :fields)
@@ -23,6 +24,10 @@ module NoBrainer::Document::Attributes
23
24
  Hash[readable_attributes.map { |k| [k, read_attribute(k)] }].with_indifferent_access.freeze
24
25
  end
25
26
 
27
+ def raw_attributes
28
+ @_attributes
29
+ end
30
+
26
31
  def _read_attribute(name)
27
32
  @_attributes[name]
28
33
  end
@@ -54,12 +59,14 @@ module NoBrainer::Document::Attributes
54
59
  end
55
60
 
56
61
  default_value = field_options[:default]
57
- default_value = default_value.call if default_value.is_a?(Proc)
62
+ default_value = instance_exec(&default_value) if default_value.is_a?(Proc)
58
63
  self.write_attribute(name, default_value)
59
64
  end
60
65
  end
61
66
 
62
67
  def assign_attributes(attrs, options={})
68
+ raise ArgumentError, "To assign attributes, please pass a hash instead of `#{attrs.class}'" unless attrs.is_a?(Hash)
69
+
63
70
  if options[:pristine]
64
71
  if options[:keep_ivars] && options[:missing_attributes].try(:[], :pluck)
65
72
  options[:missing_attributes][:pluck].keys.each { |k| @_attributes.delete(k) }
@@ -74,6 +81,7 @@ module NoBrainer::Document::Attributes
74
81
  clear_dirtiness(options)
75
82
  else
76
83
  clear_dirtiness(options) if options[:pristine]
84
+ attrs = sanitize_for_mass_assignment(attrs)
77
85
  attrs.each { |k,v| self.write_attribute(k,v) }
78
86
  end
79
87
  assign_defaults(options) if options[:pristine]
@@ -82,7 +90,7 @@ module NoBrainer::Document::Attributes
82
90
 
83
91
  def inspectable_attributes
84
92
  # TODO test that thing
85
- Hash[@_attributes.sort_by { |k,v| self.class.fields.keys.index(k.to_sym) || 2**10 }]
93
+ Hash[@_attributes.sort_by { |k,v| self.class.fields.keys.index(k.to_sym) || 2**10 }].with_indifferent_access.freeze
86
94
  end
87
95
 
88
96
  def to_s
@@ -2,7 +2,7 @@ module NoBrainer::Document::Core
2
2
  extend ActiveSupport::Concern
3
3
 
4
4
  singleton_class.class_eval do
5
- attr_accessor :_all
5
+ attr_accessor :_all, :_all_nobrainer
6
6
 
7
7
  def all
8
8
  Rails.application.eager_load! if defined?(Rails.application.eager_load!)
@@ -10,10 +10,12 @@ module NoBrainer::Document::Core
10
10
  end
11
11
  end
12
12
  self._all = []
13
+ self._all_nobrainer = []
13
14
 
14
15
  include ActiveModel::Conversion
15
16
 
16
17
  def to_key
18
+ # ActiveModel::Conversion stuff
17
19
  [pk_value]
18
20
  end
19
21
 
@@ -22,6 +24,7 @@ module NoBrainer::Document::Core
22
24
  extend ActiveModel::Naming
23
25
  extend ActiveModel::Translation
24
26
 
25
- NoBrainer::Document::Core._all << self unless self.name =~ /^NoBrainer::/
27
+ list_name = self.name =~ /^NoBrainer::/ ? :_all_nobrainer : :_all
28
+ NoBrainer::Document::Core.__send__(list_name) << self
26
29
  end
27
30
  end
@@ -2,12 +2,14 @@ module NoBrainer::Document::Criteria
2
2
  extend ActiveSupport::Concern
3
3
 
4
4
  def selector
5
- self.class.selector_for(pk_value)
5
+ # Used for writes
6
+ self.class.rql_table.get(pk_value)
6
7
  end
7
8
 
8
9
  included do
9
- cattr_accessor :default_scope_proc, :instance_accessor => false
10
10
  cattr_accessor :perf_warnings_disabled, :instance_accessor => false
11
+ singleton_class.send(:attr_accessor, :default_scopes)
12
+ self.default_scopes = []
11
13
  end
12
14
 
13
15
  module ClassMethods
@@ -21,12 +23,13 @@ module NoBrainer::Document::Criteria
21
23
  :with_cache, :without_cache, # Cache
22
24
  :count, :empty?, :any?, # Count
23
25
  :delete_all, :destroy_all, # Delete
24
- :includes, :preload, # Preload
26
+ :preload, :eager_load, # EagerLoad
25
27
  :each, :to_a, # Enumerable
26
28
  :first, :last, :first!, :last!, :sample, # First
27
29
  :min, :max, :sum, :avg, # Aggregate
28
30
  :update_all, :replace_all, # Update
29
31
  :pluck, :without, :lazy_fetch, :without_plucking, # Pluck
32
+ :find_by?, :find_by, :find_by!, :find?, :find, :find!, # Find
30
33
  :to => :all
31
34
 
32
35
  def all
@@ -42,24 +45,18 @@ module NoBrainer::Document::Criteria
42
45
  end
43
46
 
44
47
  def default_scope(criteria=nil, &block)
45
- criteria ||= block
46
- raise "store_in() must be called on the parent class" unless is_root_class?
47
- self.default_scope_proc = criteria.is_a?(Proc) ? criteria : proc { criteria }
48
- end
48
+ criteria_proc = block || (criteria.is_a?(Proc) ? criteria : proc { criteria })
49
+ raise "default_scope only accepts a criteria or a proc that returns criteria" unless criteria_proc.is_a?(Proc)
49
50
 
50
- def selector_for(pk)
51
- rql_table.get(pk)
52
- end
53
-
54
- def find?(pk)
55
- attrs = NoBrainer.run { selector_for(pk) }
56
- new_from_db(attrs).tap { |doc| doc.run_callbacks(:find) } if attrs
51
+ ([self] + self.descendants).each do |model|
52
+ model.default_scopes << criteria_proc
53
+ end
57
54
  end
58
55
 
59
- def find(pk)
60
- find?(pk).tap { |doc| raise NoBrainer::Error::DocumentNotFound, "#{self} #{pk_name}: #{pk} not found" unless doc }
56
+ def inherited(subclass)
57
+ subclass.default_scopes = self.default_scopes.dup
58
+ super
61
59
  end
62
- alias_method :find!, :find
63
60
 
64
61
  def disable_perf_warnings
65
62
  self.perf_warnings_disabled = true
@@ -31,14 +31,10 @@ module NoBrainer::Document::Dirty
31
31
  changes.keys
32
32
  end
33
33
 
34
- def read_attribute_for_change(attr)
35
- read_attribute(attr)
36
- end
37
-
38
34
  def changes
39
35
  result = {}.with_indifferent_access
40
36
  @_old_attributes.each do |attr, old_value|
41
- current_value = read_attribute_for_change(attr)
37
+ current_value = read_attribute(attr)
42
38
  if current_value != old_value || !@_old_attributes_keys.include?(attr)
43
39
  result[attr] = [old_value, current_value]
44
40
  end
@@ -46,16 +42,15 @@ module NoBrainer::Document::Dirty
46
42
  result
47
43
  end
48
44
 
49
- def attribute_may_change(*args)
50
- attr = args.first
51
- current_value = begin
52
- case args.size
53
- when 1 then assert_access_field(attr); read_attribute_for_change(attr)
54
- when 2 then args.last
55
- else raise
45
+ class None; end
46
+ def attribute_may_change(attr, current_value = None)
47
+ if current_value == None
48
+ current_value = begin
49
+ assert_access_field(attr)
50
+ read_attribute(attr)
51
+ rescue NoBrainer::Error::MissingAttribute => e
52
+ e
56
53
  end
57
- rescue NoBrainer::Error::MissingAttribute => e
58
- e
59
54
  end
60
55
 
61
56
  unless @_old_attributes.has_key?(attr)
@@ -84,7 +79,7 @@ module NoBrainer::Document::Dirty
84
79
  inject_in_layer :dirty_tracking do
85
80
  define_method("#{attr}_change") do
86
81
  if @_old_attributes.has_key?(attr)
87
- result = [@_old_attributes[attr], read_attribute_for_change(attr)]
82
+ result = [@_old_attributes[attr], read_attribute(attr)]
88
83
  result if result.first != result.last || !@_old_attributes_keys.include?(attr)
89
84
  end
90
85
  end
@@ -94,7 +89,7 @@ module NoBrainer::Document::Dirty
94
89
  end
95
90
 
96
91
  define_method("#{attr}_was") do
97
- @_old_attributes.has_key?(attr) ? @_old_attributes[attr] : read_attribute_for_change(attr)
92
+ @_old_attributes.has_key?(attr) ? @_old_attributes[attr] : read_attribute(attr)
98
93
  end
99
94
  end
100
95
  end
@@ -24,7 +24,7 @@ class NoBrainer::Document::Index::MetaStore
24
24
  def self.on(db_name, &block)
25
25
  old_db_name = Thread.current[:nobrainer_meta_store_db]
26
26
  Thread.current[:nobrainer_meta_store_db] = db_name
27
- NoBrainer.with(:auto_create_tables => true) { block.call }
27
+ block.call
28
28
  ensure
29
29
  Thread.current[:nobrainer_meta_store_db] = old_db_name
30
30
  end
@@ -14,12 +14,6 @@ module NoBrainer::Document::Index
14
14
  def index(name, *args)
15
15
  name = name.to_sym
16
16
  options = args.extract_options!
17
-
18
- if options[:as]
19
- STDERR.puts "[NoBrainer] `:as' is deprecated and will be removed. Please use `:store_as' instead (from the #{self} model)"
20
- options[:store_as] = options.delete(:as)
21
- end
22
-
23
17
  options.assert_valid_keys(*VALID_INDEX_OPTIONS)
24
18
 
25
19
  raise "Too many arguments: #{args}" if args.size > 1
@@ -29,7 +29,7 @@ module NoBrainer::Document::Persistance
29
29
 
30
30
  def _reload(options={})
31
31
  attrs = NoBrainer.run { _reload_selector(options) }
32
- raise NoBrainer::Error::DocumentNotFound, "#{self.class} #{self.class.pk_name}: #{pk_value} not found" unless attrs
32
+ raise NoBrainer::Error::DocumentNotFound, "#{self.class} :#{self.class.pk_name}=>\"#{pk_value}\" not found" unless attrs
33
33
 
34
34
  options = options.merge(:pristine => true, :from_db => true)
35
35
 
@@ -113,13 +113,11 @@ module NoBrainer::Document::Persistance
113
113
  assign_attributes(attrs, options)
114
114
  save?(options)
115
115
  end
116
- alias_method :update_attributes?, :update?
117
116
 
118
117
  def update(*args)
119
118
  update?(*args) or raise NoBrainer::Error::DocumentInvalid, self
120
119
  nil
121
120
  end
122
- alias_method :update_attributes, :update
123
121
 
124
122
  def update!(*args)
125
123
  update(*args)
@@ -127,6 +125,18 @@ module NoBrainer::Document::Persistance
127
125
  end
128
126
  alias_method :update_attributes!, :update!
129
127
 
128
+ def update_attributes?(*args)
129
+ update?(*args).tap { STDERR.puts "[NoBrainer] update_attributes?() is deprecated. Please use update?() instead" }
130
+ end
131
+
132
+ def update_attributes(*args)
133
+ update(*args).tap { STDERR.puts "[NoBrainer] update_attributes() is deprecated. Please use update() instead" }
134
+ end
135
+
136
+ def update_attributes!(*args)
137
+ update!(*args).tap { STDERR.puts "[NoBrainer] update_attributes!() is deprecated. Please use update() instead" }
138
+ end
139
+
130
140
  def delete
131
141
  unless @destroyed
132
142
  NoBrainer.run { selector.delete }
@@ -16,13 +16,13 @@ module NoBrainer::Document::StoreIn
16
16
 
17
17
  def database_name
18
18
  db = self.store_in_options[:database]
19
- db.is_a?(Proc) ? db.call : db
19
+ (db.is_a?(Proc) ? db.call : db).try(:to_s)
20
20
  end
21
21
 
22
22
  def table_name
23
23
  table = store_in_options[:table]
24
24
  table_name = table.is_a?(Proc) ? table.call : table
25
- table_name || root_class.name.tableize.gsub('/', '__')
25
+ table_name.try(:to_s) || root_class.name.tableize.gsub('/', '__')
26
26
  end
27
27
 
28
28
  def rql_table
@@ -4,7 +4,7 @@ class NoBrainer::Binary
4
4
  def self.to_s; inspect; end
5
5
  def self.name; inspect; end
6
6
 
7
- module NoBrainerExtentions
7
+ module NoBrainerExtensions
8
8
  InvalidType = NoBrainer::Error::InvalidType
9
9
 
10
10
  def nobrainer_cast_user_to_model(value)
@@ -13,10 +13,6 @@ class NoBrainer::Binary
13
13
  else raise InvalidType
14
14
  end
15
15
  end
16
-
17
- def nobrainer_cast_db_to_model(value)
18
- value.is_a?(String) ? RethinkDB::Binary.new(value) : value
19
- end
20
16
  end
21
- extend NoBrainerExtentions
17
+ extend NoBrainerExtensions
22
18
  end
@@ -1,11 +1,10 @@
1
- # We namespace our fake Boolean class to avoid polluting the global namespace
2
1
  class NoBrainer::Boolean
3
2
  def initialize; raise; end
4
3
  def self.inspect; 'Boolean'; end
5
4
  def self.to_s; inspect; end
6
5
  def self.name; inspect; end
7
6
 
8
- module NoBrainerExtentions
7
+ module NoBrainerExtensions
9
8
  InvalidType = NoBrainer::Error::InvalidType
10
9
 
11
10
  def nobrainer_cast_user_to_model(value)
@@ -21,5 +20,5 @@ class NoBrainer::Boolean
21
20
  end
22
21
  end
23
22
  end
24
- extend NoBrainerExtentions
23
+ extend NoBrainerExtensions
25
24
  end
@@ -1,5 +1,5 @@
1
1
  class Date
2
- module NoBrainerExtentions
2
+ module NoBrainerExtensions
3
3
  InvalidType = NoBrainer::Error::InvalidType
4
4
 
5
5
  def nobrainer_cast_user_to_model(value)
@@ -22,5 +22,5 @@ class Date
22
22
  value.is_a?(Date) ? Time.utc(value.year, value.month, value.day) : value
23
23
  end
24
24
  end
25
- extend NoBrainerExtentions
25
+ extend NoBrainerExtensions
26
26
  end
@@ -1,5 +1,5 @@
1
1
  class Float
2
- module NoBrainerExtentions
2
+ module NoBrainerExtensions
3
3
  InvalidType = NoBrainer::Error::InvalidType
4
4
 
5
5
  def nobrainer_cast_user_to_model(value)
@@ -16,5 +16,5 @@ class Float
16
16
  end
17
17
  end
18
18
  end
19
- extend NoBrainerExtentions
19
+ extend NoBrainerExtensions
20
20
  end
@@ -0,0 +1 @@
1
+ # Look in lib/no_brainer/geo.rb instead
@@ -1,5 +1,5 @@
1
1
  class Integer
2
- module NoBrainerExtentions
2
+ module NoBrainerExtensions
3
3
  InvalidType = NoBrainer::Error::InvalidType
4
4
 
5
5
  def nobrainer_cast_user_to_model(value)
@@ -14,5 +14,5 @@ class Integer
14
14
  end
15
15
  end
16
16
  end
17
- extend NoBrainerExtentions
17
+ extend NoBrainerExtensions
18
18
  end
@@ -1,5 +1,5 @@
1
1
  class Set
2
- module NoBrainerExtentions
2
+ module NoBrainerExtensions
3
3
  InvalidType = NoBrainer::Error::InvalidType
4
4
 
5
5
  def nobrainer_cast_user_to_model(value)
@@ -19,5 +19,5 @@ class Set
19
19
  end
20
20
  end
21
21
 
22
- extend NoBrainerExtentions
22
+ extend NoBrainerExtensions
23
23
  end
@@ -1,5 +1,5 @@
1
1
  class String
2
- module NoBrainerExtentions
2
+ module NoBrainerExtensions
3
3
  InvalidType = NoBrainer::Error::InvalidType
4
4
 
5
5
  def nobrainer_cast_user_to_model(value)
@@ -7,8 +7,11 @@ class String
7
7
  when String then value
8
8
  when Symbol then value.to_s
9
9
  else raise InvalidType
10
+ end.tap do |str|
11
+ max_length = NoBrainer::Config.max_string_length
12
+ raise InvalidType.new(:error => { :message => :too_long, :count => max_length }) if str.size > max_length
10
13
  end
11
14
  end
12
15
  end
13
- extend NoBrainerExtentions
16
+ extend NoBrainerExtensions
14
17
  end