mattetti-couchrest 0.2.1.0 → 0.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/README.md +6 -31
  2. data/Rakefile +1 -1
  3. data/examples/model/example.rb +13 -19
  4. data/lib/couchrest/core/database.rb +4 -3
  5. data/lib/couchrest/core/model.rb +615 -0
  6. data/lib/couchrest/core/response.rb +4 -5
  7. data/lib/couchrest/core/server.rb +1 -1
  8. data/lib/couchrest/mixins/callbacks.rb +33 -74
  9. data/lib/couchrest/mixins/design_doc.rb +1 -2
  10. data/lib/couchrest/mixins/document_queries.rb +1 -1
  11. data/lib/couchrest/mixins/extended_document_mixins.rb +1 -2
  12. data/lib/couchrest/mixins/properties.rb +3 -8
  13. data/lib/couchrest/mixins/validation.rb +1 -2
  14. data/lib/couchrest/mixins/views.rb +5 -5
  15. data/lib/couchrest/monkeypatches.rb +48 -65
  16. data/lib/couchrest/more/extended_document.rb +8 -75
  17. data/lib/couchrest/more/property.rb +1 -12
  18. data/lib/couchrest/support/class.rb +132 -148
  19. data/lib/couchrest.rb +8 -33
  20. data/spec/couchrest/core/database_spec.rb +23 -28
  21. data/spec/couchrest/core/model_spec.rb +856 -0
  22. data/spec/couchrest/more/casted_model_spec.rb +0 -14
  23. data/spec/couchrest/more/extended_doc_spec.rb +4 -450
  24. data/spec/couchrest/more/property_spec.rb +5 -16
  25. data/spec/spec_helper.rb +0 -4
  26. metadata +3 -16
  27. data/lib/couchrest/mixins/extended_attachments.rb +0 -68
  28. data/lib/couchrest/validation/validators/confirmation_validator.rb +0 -99
  29. data/spec/couchrest/more/casted_extended_doc_spec.rb +0 -40
  30. data/spec/couchrest/more/extended_doc_attachment_spec.rb +0 -129
  31. data/spec/couchrest/more/extended_doc_view_spec.rb +0 -206
  32. data/spec/couchrest/support/class_spec.rb +0 -59
  33. data/spec/fixtures/more/article.rb +0 -34
  34. data/spec/fixtures/more/course.rb +0 -14
  35. data/spec/fixtures/more/event.rb +0 -6
  36. data/spec/fixtures/more/person.rb +0 -8
  37. data/spec/fixtures/more/question.rb +0 -6
@@ -1,7 +1,6 @@
1
1
  require File.join(File.dirname(__FILE__), '..', 'support', 'class')
2
2
 
3
3
  # Extracted from ActiveSupport::Callbacks written by Yehuda Katz
4
- # http://github.com/wycats/rails/raw/abstract_controller/activesupport/lib/active_support/new_callbacks.rb
5
4
  # http://github.com/wycats/rails/raw/18b405f154868204a8f332888871041a7bad95e1/activesupport/lib/active_support/callbacks.rb
6
5
 
7
6
  module CouchRest
@@ -12,7 +11,7 @@ module CouchRest
12
11
  #
13
12
  # Example:
14
13
  # class Storage
15
- # include ActiveSupport::Callbacks
14
+ # include CouchRest::Callbacks
16
15
  #
17
16
  # define_callbacks :save
18
17
  # end
@@ -46,7 +45,7 @@ module CouchRest
46
45
  #
47
46
  # Example:
48
47
  # class Storage
49
- # include ActiveSupport::Callbacks
48
+ # include CouchRest::Callbacks
50
49
  #
51
50
  # define_callbacks :save
52
51
  #
@@ -86,8 +85,8 @@ module CouchRest
86
85
  klass.extend ClassMethods
87
86
  end
88
87
 
89
- def run_callbacks(kind, options = {}, &blk)
90
- send("_run_#{kind}_callbacks", &blk)
88
+ def run_callbacks(kind, options = {})
89
+ send("_run_#{kind}_callbacks")
91
90
  end
92
91
 
93
92
  class Callback
@@ -167,13 +166,9 @@ module CouchRest
167
166
 
168
167
  # This will supply contents for before and around filters, and no
169
168
  # contents for after filters (for the forward pass).
170
- def start(key = nil, options = {})
171
- object, terminator = (options || {}).values_at(:object, :terminator)
172
-
169
+ def start(key = nil, object = nil)
173
170
  return if key && !object.send("_one_time_conditions_valid_#{@callback_id}?")
174
171
 
175
- terminator ||= false
176
-
177
172
  # options[0] is the compiled form of supplied conditions
178
173
  # options[1] is the "end" for the conditional
179
174
 
@@ -182,14 +177,8 @@ module CouchRest
182
177
  # if condition # before_save :filter_name, :if => :condition
183
178
  # filter_name
184
179
  # end
185
- filter = <<-RUBY_EVAL
186
- unless halted
187
- result = #{@filter}
188
- halted ||= (#{terminator})
189
- end
190
- RUBY_EVAL
191
- [@compiled_options[0], filter, @compiled_options[1]].compact.join("\n")
192
- else
180
+ [@compiled_options[0], @filter, @compiled_options[1]].compact.join("\n")
181
+ elsif @compiled_options[0]
193
182
  # Compile around filters with conditions into proxy methods
194
183
  # that contain the conditions.
195
184
  #
@@ -207,8 +196,8 @@ module CouchRest
207
196
 
208
197
  name = "_conditional_callback_#{@kind}_#{next_id}"
209
198
  txt = <<-RUBY_EVAL
210
- def #{name}(halted)
211
- #{@compiled_options[0] || "if true"} && !halted
199
+ def #{name}
200
+ #{@compiled_options[0]}
212
201
  #{@filter} do
213
202
  yield self
214
203
  end
@@ -218,16 +207,16 @@ module CouchRest
218
207
  end
219
208
  RUBY_EVAL
220
209
  @klass.class_eval(txt)
221
- "#{name}(halted) do"
210
+ "#{name} do"
211
+ else
212
+ "#{@filter} do"
222
213
  end
223
214
  end
224
215
  end
225
216
 
226
217
  # This will supply contents for around and after filters, but not
227
218
  # before filters (for the backward pass).
228
- def end(key = nil, options = {})
229
- object = (options || {})[:object]
230
-
219
+ def end(key = nil, object = nil)
231
220
  return if key && !object.send("_one_time_conditions_valid_#{@callback_id}?")
232
221
 
233
222
  if @kind == :around || @kind == :after
@@ -310,7 +299,7 @@ module CouchRest
310
299
  # This method_missing is supplied to catch callbacks with keys and create
311
300
  # the appropriate callback for future use.
312
301
  def method_missing(meth, *args, &blk)
313
- if meth.to_s =~ /_run__([\w:]+)__(\w+)__(\w+)__callbacks/
302
+ if meth.to_s =~ /_run_(\w+)_(\w+)_(\w+)_callbacks/
314
303
  return self.class._create_and_run_keyed_callback($1, $2.to_sym, $3.to_sym, self, &blk)
315
304
  end
316
305
  super
@@ -318,31 +307,25 @@ module CouchRest
318
307
 
319
308
  # An Array with a compile method
320
309
  class CallbackChain < Array
321
- def initialize(symbol)
322
- @symbol = symbol
323
- end
324
-
325
- def compile(key = nil, options = {})
310
+ def compile(key = nil, object = nil)
326
311
  method = []
327
- method << "halted = false"
328
312
  each do |callback|
329
- method << callback.start(key, options)
313
+ method << callback.start(key, object)
330
314
  end
331
- method << "yield self if block_given?"
315
+ method << "yield self"
332
316
  reverse_each do |callback|
333
- method << callback.end(key, options)
317
+ method << callback.end(key, object)
334
318
  end
335
319
  method.compact.join("\n")
336
320
  end
337
321
 
338
322
  def clone(klass)
339
- chain = CallbackChain.new(@symbol)
340
- chain.push(*map {|c| c.clone(klass)})
323
+ CallbackChain.new(map {|c| c.clone(klass)})
341
324
  end
342
325
  end
343
326
 
344
327
  module ClassMethods
345
- CHAINS = {:before => :before, :around => :before, :after => :after} unless self.const_defined?("CHAINS")
328
+ CHAINS = {:before => :before, :around => :before, :after => :after}
346
329
 
347
330
  # Make the _run_save_callbacks method. The generated method takes
348
331
  # a block that it'll yield to. It'll call the before and around filters
@@ -355,18 +338,16 @@ module CouchRest
355
338
  # The _run_save_callbacks method can optionally take a key, which
356
339
  # will be used to compile an optimized callback method for each
357
340
  # key. See #define_callbacks for more information.
358
- def _define_runner(symbol, str, options)
359
- str = <<-RUBY_EVAL
341
+ def _define_runner(symbol, str, options)
342
+ self.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
360
343
  def _run_#{symbol}_callbacks(key = nil)
361
344
  if key
362
- send("_run__\#{self.class.name.split("::").last}__#{symbol}__\#{key}__callbacks") { yield if block_given? }
345
+ send("_run_\#{self.class}_#{symbol}_\#{key}_callbacks") { yield }
363
346
  else
364
347
  #{str}
365
348
  end
366
349
  end
367
350
  RUBY_EVAL
368
-
369
- class_eval str, __FILE__, __LINE__ + 1
370
351
 
371
352
  before_name, around_name, after_name =
372
353
  options.values_at(:before, :after, :around)
@@ -378,18 +359,15 @@ module CouchRest
378
359
  def _create_and_run_keyed_callback(klass, kind, key, obj, &blk)
379
360
  @_keyed_callbacks ||= {}
380
361
  @_keyed_callbacks[[kind, key]] ||= begin
381
- str = self.send("_#{kind}_callbacks").compile(key, :object => obj, :terminator => self.send("_#{kind}_terminator"))
382
-
362
+ str = self.send("_#{kind}_callbacks").compile(key, obj)
383
363
  self.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
384
- def _run__#{klass.split("::").last}__#{kind}__#{key}__callbacks
364
+ def _run_#{klass}_#{kind}_#{key}_callbacks
385
365
  #{str}
386
366
  end
387
367
  RUBY_EVAL
388
-
389
368
  true
390
369
  end
391
-
392
- obj.send("_run__#{klass.split("::").last}__#{kind}__#{key}__callbacks", &blk)
370
+ obj.send("_run_#{klass}_#{kind}_#{key}_callbacks", &blk)
393
371
  end
394
372
 
395
373
  # Define callbacks.
@@ -424,32 +402,20 @@ module CouchRest
424
402
  # method that took into consideration the per_key conditions. This
425
403
  # is a speed improvement for ActionPack.
426
404
  def define_callbacks(*symbols)
427
- terminator = symbols.pop if symbols.last.is_a?(String)
428
405
  symbols.each do |symbol|
429
- self.class_inheritable_accessor("_#{symbol}_terminator")
430
- self.send("_#{symbol}_terminator=", terminator)
431
406
  self.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
432
407
  class_inheritable_accessor :_#{symbol}_callbacks
433
- self._#{symbol}_callbacks = CallbackChain.new(:#{symbol})
408
+ self._#{symbol}_callbacks = CallbackChain.new
434
409
 
435
- def self.#{symbol}_callback(*filters, &blk)
436
- type = [:before, :after, :around].include?(filters.first) ? filters.shift : :before
410
+ def self.#{symbol}_callback(type, *filters, &blk)
437
411
  options = filters.last.is_a?(Hash) ? filters.pop : {}
438
412
  filters.unshift(blk) if block_given?
439
-
440
- filters.map! do |filter|
441
- # overrides parent class
442
- self._#{symbol}_callbacks.delete_if {|c| c.matches?(type, :#{symbol}, filter)}
443
- Callback.new(filter, type, options.dup, self, :#{symbol})
444
- end
413
+ filters.map! {|f| Callback.new(f, type, options.dup, self, :#{symbol})}
445
414
  self._#{symbol}_callbacks.push(*filters)
446
- _define_runner(:#{symbol},
447
- self._#{symbol}_callbacks.compile(nil, :terminator => _#{symbol}_terminator),
448
- options)
415
+ _define_runner(:#{symbol}, self._#{symbol}_callbacks.compile, options)
449
416
  end
450
417
 
451
- def self.skip_#{symbol}_callback(*filters, &blk)
452
- type = [:before, :after, :around].include?(filters.first) ? filters.shift : :before
418
+ def self.skip_#{symbol}_callback(type, *filters, &blk)
453
419
  options = filters.last.is_a?(Hash) ? filters.pop : {}
454
420
  filters.unshift(blk) if block_given?
455
421
  filters.each do |filter|
@@ -462,22 +428,15 @@ module CouchRest
462
428
  else
463
429
  self._#{symbol}_callbacks.delete(filter)
464
430
  end
465
- _define_runner(:#{symbol},
466
- self._#{symbol}_callbacks.compile(nil, :terminator => _#{symbol}_terminator),
467
- options)
431
+ _define_runner(:#{symbol}, self._#{symbol}_callbacks.compile, options)
468
432
  end
469
433
 
470
434
  end
471
435
 
472
- def self.reset_#{symbol}_callbacks
473
- self._#{symbol}_callbacks = CallbackChain.new(:#{symbol})
474
- _define_runner(:#{symbol}, self._#{symbol}_callbacks.compile, {})
475
- end
476
-
477
436
  self.#{symbol}_callback(:before)
478
437
  RUBY_EVAL
479
438
  end
480
439
  end
481
440
  end
482
441
  end
483
- end
442
+ end
@@ -14,9 +14,8 @@ module CouchRest
14
14
  end
15
15
 
16
16
  def design_doc_slug
17
- return design_doc_slug_cache if (design_doc_slug_cache && design_doc_fresh)
17
+ return design_doc_slug_cache if design_doc_slug_cache && design_doc_fresh
18
18
  funcs = []
19
- design_doc ||= Design.new(default_design_doc)
20
19
  design_doc['views'].each do |name, view|
21
20
  funcs << "#{name}/#{view['map']}#{view['reduce']}"
22
21
  end
@@ -16,7 +16,7 @@ module CouchRest
16
16
  unless design_doc_fresh
17
17
  refresh_design_doc
18
18
  end
19
- view(:all, opts, &block)
19
+ view :all, opts, &block
20
20
  end
21
21
 
22
22
  # Load the first document that have the "couchrest-type" field equal to
@@ -2,5 +2,4 @@ require File.join(File.dirname(__FILE__), 'properties')
2
2
  require File.join(File.dirname(__FILE__), 'document_queries')
3
3
  require File.join(File.dirname(__FILE__), 'views')
4
4
  require File.join(File.dirname(__FILE__), 'design_doc')
5
- require File.join(File.dirname(__FILE__), 'validation')
6
- require File.join(File.dirname(__FILE__), 'extended_attachments')
5
+ require File.join(File.dirname(__FILE__), 'validation')
@@ -40,8 +40,8 @@ module CouchRest
40
40
  key = self.has_key?(property.name) ? property.name : property.name.to_sym
41
41
  target = property.type
42
42
  if target.is_a?(Array)
43
- next unless self[key]
44
43
  klass = ::CouchRest.constantize(target[0])
44
+
45
45
  self[property.name] = self[key].collect do |value|
46
46
  # Auto parse Time objects
47
47
  obj = ( (property.init_method == 'new') && klass == Time) ? Time.parse(value) : klass.send(property.init_method, value)
@@ -55,14 +55,9 @@ module CouchRest
55
55
  else
56
56
  # Let people use :send as a Time parse arg
57
57
  klass = ::CouchRest.constantize(target)
58
- # I'm not convince we should or should not create a new instance if we are casting a doc/extended doc without default value and nothing was passed
59
- # unless (property.casted &&
60
- # (klass.superclass == CouchRest::ExtendedDocument || klass.superclass == CouchRest::Document) &&
61
- # (self[key].nil? || property.default.nil?))
62
58
  klass.send(property.init_method, self[key])
63
- #end
64
59
  end
65
- self[property.name].casted_by = self if self[property.name].respond_to?(:casted_by)
60
+ self[key].casted_by = self if self[key].respond_to?(:casted_by)
66
61
  end
67
62
  end
68
63
  end
@@ -70,7 +65,7 @@ module CouchRest
70
65
  module ClassMethods
71
66
 
72
67
  def property(name, options={})
73
- define_property(name, options) unless self.properties.map{|p| p.name}.include?(name.to_s)
68
+ define_property(name, options) unless properties.map{|p| p.name}.include?(name.to_s)
74
69
  end
75
70
 
76
71
  protected
@@ -43,7 +43,6 @@ require File.join(dir, 'validators', 'format_validator')
43
43
  require File.join(dir, 'validators', 'length_validator')
44
44
  require File.join(dir, 'validators', 'numeric_validator')
45
45
  require File.join(dir, 'validators', 'method_validator')
46
- require File.join(dir, 'validators', 'confirmation_validator')
47
46
 
48
47
  module CouchRest
49
48
  module Validation
@@ -148,7 +147,7 @@ module CouchRest
148
147
  module ClassMethods
149
148
  include CouchRest::Validation::ValidatesPresent
150
149
  include CouchRest::Validation::ValidatesAbsent
151
- include CouchRest::Validation::ValidatesIsConfirmed
150
+ # include CouchRest::Validation::ValidatesIsConfirmed
152
151
  # include CouchRest::Validation::ValidatesIsPrimitive
153
152
  # include CouchRest::Validation::ValidatesIsAccepted
154
153
  include CouchRest::Validation::ValidatesFormat
@@ -95,7 +95,7 @@ module CouchRest
95
95
  end
96
96
 
97
97
  # Dispatches to any named view.
98
- def view(name, query={}, &block)
98
+ def view name, query={}, &block
99
99
  unless design_doc_fresh
100
100
  refresh_design_doc
101
101
  end
@@ -128,9 +128,9 @@ module CouchRest
128
128
 
129
129
  private
130
130
 
131
- def fetch_view_with_docs(name, opts, raw=false, &block)
132
- if raw || (opts.has_key?(:include_docs) && opts[:include_docs] == false)
133
- fetch_view(name, opts, &block)
131
+ def fetch_view_with_docs name, opts, raw=false, &block
132
+ if raw
133
+ fetch_view name, opts, &block
134
134
  else
135
135
  begin
136
136
  view = fetch_view name, opts.merge({:include_docs => true}), &block
@@ -138,7 +138,7 @@ module CouchRest
138
138
  rescue
139
139
  # fallback for old versions of couchdb that don't
140
140
  # have include_docs support
141
- view = fetch_view(name, opts, &block)
141
+ view = fetch_view name, opts, &block
142
142
  view['rows'].collect{|r|new(database.get(r['id']))} if view['rows']
143
143
  end
144
144
  end
@@ -31,19 +31,13 @@ if RUBY_VERSION.to_f < 1.9
31
31
  class Net::BufferedIO #:nodoc:
32
32
  alias :old_rbuf_fill :rbuf_fill
33
33
  def rbuf_fill
34
- if @io.respond_to?(:read_nonblock)
35
- begin
34
+ begin
35
+ @rbuf << @io.read_nonblock(65536)
36
+ rescue Errno::EWOULDBLOCK
37
+ if IO.select([@io], nil, nil, @read_timeout)
36
38
  @rbuf << @io.read_nonblock(65536)
37
- rescue Errno::EWOULDBLOCK
38
- if IO.select([@io], nil, nil, @read_timeout)
39
- retry
40
- else
41
- raise Timeout::TimeoutError
42
- end
43
- end
44
- else
45
- timeout(@read_timeout) do
46
- @rbuf << @io.sysread(65536)
39
+ else
40
+ raise Timeout::TimeoutError
47
41
  end
48
42
  end
49
43
  end
@@ -62,58 +56,47 @@ module RestClient
62
56
  :url => url,
63
57
  :headers => headers)
64
58
  end
65
-
66
- # class Request
67
- #
68
- # def establish_connection(uri)
69
- # Thread.current[:connection].finish if (Thread.current[:connection] && Thread.current[:connection].started?)
70
- # p net_http_class
71
- # net = net_http_class.new(uri.host, uri.port)
72
- # net.use_ssl = uri.is_a?(URI::HTTPS)
73
- # net.verify_mode = OpenSSL::SSL::VERIFY_NONE
74
- # Thread.current[:connection] = net
75
- # Thread.current[:connection].start
76
- # Thread.current[:connection]
77
- # end
78
- #
79
- # def transmit(uri, req, payload)
80
- # setup_credentials(req)
81
- #
82
- # Thread.current[:host] ||= uri.host
83
- # Thread.current[:port] ||= uri.port
84
- #
85
- # if (Thread.current[:connection].nil? || (Thread.current[:host] != uri.host))
86
- # p "establishing a connection"
87
- # establish_connection(uri)
88
- # end
89
- #
90
- # display_log request_log
91
- # http = Thread.current[:connection]
92
- # http.read_timeout = @timeout if @timeout
93
- #
94
- # begin
95
- # res = http.request(req, payload)
96
- # rescue
97
- # p "Net::HTTP connection failed, reconnecting"
98
- # establish_connection(uri)
99
- # http = Thread.current[:connection]
100
- # require 'ruby-debug'
101
- # debugger
102
- # req.body_stream = nil
103
- #
104
- # res = http.request(req, payload)
105
- # display_log response_log(res)
106
- # result res
107
- # else
108
- # display_log response_log(res)
109
- # process_result res
110
- # end
111
- #
112
- # rescue EOFError
113
- # raise RestClient::ServerBrokeConnection
114
- # rescue Timeout::Error
115
- # raise RestClient::RequestTimeout
116
- # end
117
- # end
118
59
 
60
+ class Request
61
+ def transmit(uri, req, payload)
62
+ setup_credentials(req)
63
+
64
+ Thread.current[:host] ||= uri.host
65
+ Thread.current[:port] ||= uri.port
66
+
67
+ net = net_http_class.new(uri.host, uri.port)
68
+
69
+ if Thread.current[:connection].nil? || Thread.current[:host] != uri.host
70
+ Thread.current[:connection].finish if (Thread.current[:connection] && Thread.current[:connection].started?)
71
+ net.use_ssl = uri.is_a?(URI::HTTPS)
72
+ net.verify_mode = OpenSSL::SSL::VERIFY_NONE
73
+ Thread.current[:connection] = net
74
+ Thread.current[:connection].start
75
+ end
76
+
77
+ display_log request_log
78
+ http = Thread.current[:connection]
79
+
80
+ http.read_timeout = @timeout if @timeout
81
+ begin
82
+ res = http.request(req, payload)
83
+ rescue
84
+ # p "Net::HTTP connection failed, reconnecting"
85
+ Thread.current[:connection].finish
86
+ http = Thread.current[:connection] = net
87
+ Thread.current[:connection].start
88
+ res = http.request(req, payload)
89
+ display_log response_log(res)
90
+ process_result res
91
+ else
92
+ display_log response_log(res)
93
+ process_result res
94
+ end
95
+
96
+ rescue EOFError
97
+ raise RestClient::ServerBrokeConnection
98
+ rescue Timeout::Error
99
+ raise RestClient::RequestTimeout
100
+ end
101
+ end
119
102
  end
@@ -1,5 +1,4 @@
1
1
  begin
2
- # still required for Time parsing and pluralization in the validation
3
2
  require 'extlib'
4
3
  rescue
5
4
  puts "CouchRest::ExtendedDocument still requires extlib (not for much longer). This is left out of the gemspec on purpose."
@@ -18,24 +17,18 @@ module CouchRest
18
17
  include CouchRest::Mixins::DocumentQueries
19
18
  include CouchRest::Mixins::Views
20
19
  include CouchRest::Mixins::DesignDoc
21
- include CouchRest::Mixins::ExtendedAttachments
22
20
 
23
21
  def self.inherited(subklass)
24
22
  subklass.send(:include, CouchRest::Mixins::Properties)
25
23
  end
26
24
 
27
- # Accessors
28
- attr_accessor :casted_by
29
-
30
25
  # Callbacks
31
- define_callbacks :create
32
26
  define_callbacks :save
33
- define_callbacks :update
34
27
  define_callbacks :destroy
35
28
 
36
- def initialize(passed_keys={})
37
- apply_defaults # defined in CouchRest::Mixins::Properties
29
+ def initialize(keys={})
38
30
  super
31
+ apply_defaults # defined in CouchRest::Mixins::Properties
39
32
  cast_keys # defined in CouchRest::Mixins::Properties
40
33
  unless self['_id'] && self['_rev']
41
34
  self['couchrest-type'] = self.class.to_s
@@ -79,16 +72,6 @@ module CouchRest
79
72
  end
80
73
  end
81
74
 
82
- # Temp solution to make the view_by methods available
83
- def self.method_missing(m, *args)
84
- if has_view?(m)
85
- query = args.shift || {}
86
- view(m, query, *args)
87
- else
88
- super
89
- end
90
- end
91
-
92
75
  ### instance methods
93
76
 
94
77
  # Returns the Class properties
@@ -104,7 +87,7 @@ module CouchRest
104
87
  # missing. In case of error, no attributes are changed.
105
88
  def update_attributes_without_saving(hash)
106
89
  hash.each do |k, v|
107
- raise NoMethodError, "#{k}= method not available, use property :#{k}" unless self.respond_to?("#{k}=")
90
+ raise NoMethodError, "#{k}= method not available, use key_accessor or key_writer :#{k}" unless self.respond_to?("#{k}=")
108
91
  end
109
92
  hash.each do |k, v|
110
93
  self.send("#{k}=",v)
@@ -122,62 +105,12 @@ module CouchRest
122
105
  # for compatibility with old-school frameworks
123
106
  alias :new_record? :new_document?
124
107
 
125
- # Trigger the callbacks (before, after, around)
126
- # and create the document
127
- # It's important to have a create callback since you can't check if a document
128
- # was new after you saved it
129
- #
130
- # When creating a document, both the create and the save callbacks will be triggered.
131
- def create(bulk = false)
132
- caught = catch(:halt) do
133
- _run_create_callbacks do
134
- _run_save_callbacks do
135
- create_without_callbacks(bulk)
136
- end
137
- end
138
- end
139
- end
140
-
141
- # unlike save, create returns the newly created document
142
- def create_without_callbacks(bulk =false)
143
- raise ArgumentError, "a document requires a database to be created to (The document or the #{self.class} default database were not set)" unless database
144
- set_unique_id if new_document? && self.respond_to?(:set_unique_id)
145
- result = database.save_doc(self, bulk)
146
- (result["ok"] == true) ? self : false
147
- end
148
-
149
- # Creates the document in the db. Raises an exception
150
- # if the document is not created properly.
151
- def create!
152
- raise "#{self.inspect} failed to save" unless self.create
153
- end
154
-
155
- # Trigger the callbacks (before, after, around)
156
- # only if the document isn't new
157
- def update(bulk = false)
158
- caught = catch(:halt) do
159
- if self.new_document?
160
- save(bulk)
161
- else
162
- _run_update_callbacks do
163
- _run_save_callbacks do
164
- save_without_callbacks(bulk)
165
- end
166
- end
167
- end
168
- end
169
- end
170
-
171
108
  # Trigger the callbacks (before, after, around)
172
109
  # and save the document
173
110
  def save(bulk = false)
174
111
  caught = catch(:halt) do
175
- if self.new_document?
176
- _run_save_callbacks do
177
- save_without_callbacks(bulk)
178
- end
179
- else
180
- update(bulk)
112
+ _run_save_callbacks do
113
+ save_without_callbacks(bulk)
181
114
  end
182
115
  end
183
116
  end
@@ -191,7 +124,7 @@ module CouchRest
191
124
  result["ok"] == true
192
125
  end
193
126
 
194
- # Saves the document to the db using save. Raises an exception
127
+ # Saves the document to the db using create or update. Raises an exception
195
128
  # if the document is not saved properly.
196
129
  def save!
197
130
  raise "#{self.inspect} failed to save" unless self.save
@@ -200,10 +133,10 @@ module CouchRest
200
133
  # Deletes the document from the database. Runs the :destroy callbacks.
201
134
  # Removes the <tt>_id</tt> and <tt>_rev</tt> fields, preparing the
202
135
  # document to be saved to a new <tt>_id</tt>.
203
- def destroy(bulk=false)
136
+ def destroy
204
137
  caught = catch(:halt) do
205
138
  _run_destroy_callbacks do
206
- result = database.delete_doc(self, bulk)
139
+ result = database.delete_doc self
207
140
  if result['ok']
208
141
  self['_rev'] = nil
209
142
  self['_id'] = nil
@@ -7,24 +7,13 @@ module CouchRest
7
7
  # attribute to define
8
8
  def initialize(name, type = nil, options = {})
9
9
  @name = name.to_s
10
- parse_type(type)
10
+ @type = type.nil? ? 'String' : type.to_s
11
11
  parse_options(options)
12
12
  self
13
13
  end
14
14
 
15
15
 
16
16
  private
17
-
18
- def parse_type(type)
19
- if type.nil?
20
- @type = 'String'
21
- elsif type.is_a?(Array) && type.empty?
22
- @type = 'Array'
23
- else
24
- @type = type.is_a?(Array) ? [type.first.to_s] : type.to_s
25
- end
26
- end
27
-
28
17
  def parse_options(options)
29
18
  return if options.empty?
30
19
  @validation_format = options.delete(:format) if options[:format]