couchbase-model 0.2.0 → 0.3.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.
@@ -1,3 +1,12 @@
1
+ ## 0.3.0 / 2012-09-22
2
+
3
+ * Implement belongs_to asscociation
4
+ * Use ActiveModel naming and conversion
5
+ * Define persisted? method
6
+ * Allow optional CAS value for mutators
7
+ * Use replace in save method. Thanks to @scalabl3
8
+ * Add callbacks for :save, :create, :update and :delete methods
9
+
1
10
  ## 0.2.0 / 2012-09-18
2
11
 
3
12
  * Add Rails 3 configuration possibilities, allow configuring
@@ -20,4 +20,9 @@ require 'couchbase/model'
20
20
  # If we are using Rails then we will include the Couchbase railtie.
21
21
  if defined?(Rails)
22
22
  require "couchbase/railtie"
23
+
24
+ class Couchbase::Model
25
+ extend ActiveModel::Naming
26
+ include ActiveModel::Conversion
27
+ end
23
28
  end
@@ -25,6 +25,12 @@ require 'couchbase/model/configuration'
25
25
  unless Object.respond_to?(:singleton_class)
26
26
  require 'couchbase/model/ext/singleton_class'
27
27
  end
28
+ unless "".respond_to?(:constantize)
29
+ require 'couchbase/model/ext/constantize'
30
+ end
31
+ unless "".respond_to?(:camelize)
32
+ require 'couchbase/model/ext/camelize'
33
+ end
28
34
 
29
35
  module Couchbase
30
36
 
@@ -274,8 +280,8 @@ module Couchbase
274
280
  options = names.pop
275
281
  end
276
282
  names.each do |name|
277
- attributes[name] = options[:default]
278
283
  name = name.to_sym
284
+ attributes[name] = options[:default]
279
285
  next if self.instance_methods.include?(name)
280
286
  define_method(name) do
281
287
  @_attributes[name]
@@ -319,6 +325,35 @@ module Couchbase
319
325
  end
320
326
  end
321
327
 
328
+ # Defines a belongs_to association for the model
329
+ #
330
+ # @since 0.3.0
331
+ #
332
+ # @param [Symbol, String] name name of the associated model
333
+ # @param [Hash] options association options
334
+ # @option options [String, Symbol] :class_name the name of the
335
+ # association class
336
+ #
337
+ # @example Define some association for a model
338
+ # class Brewery < Couchbase::Model
339
+ # attribute :name
340
+ # end
341
+ #
342
+ # class Beer < Couchbase::Model
343
+ # attribute :name, :brewery_id
344
+ # belongs_to :brewery
345
+ # end
346
+ #
347
+ # Beer.find("heineken").brewery.name
348
+ def self.belongs_to(name, options = {})
349
+ ref = "#{name}_id"
350
+ attribute(ref)
351
+ assoc = name.to_s.camelize.constantize
352
+ define_method(name) do
353
+ assoc.find(self.send(ref))
354
+ end
355
+ end
356
+
322
357
  # Find the model using +id+ attribute
323
358
  #
324
359
  # @since 0.0.1
@@ -412,15 +447,16 @@ module Couchbase
412
447
  #
413
448
  # @since 0.0.1
414
449
  #
450
+ # @param [Bignum] cas CAS value
415
451
  # @return [Couchbase::Model] The saved object
416
452
  #
417
453
  # @example Update the Post model
418
454
  # p = Post.find('hello-world')
419
455
  # p.draft = false
420
456
  # p.save
421
- def save
457
+ def save(cas = nil)
422
458
  return create if new?
423
- model.bucket.set(@id, attributes_with_values)
459
+ model.bucket.replace(@id, attributes_with_values, :cas => cas)
424
460
  self
425
461
  end
426
462
 
@@ -430,10 +466,11 @@ module Couchbase
430
466
  #
431
467
  # @param [Hash] attrs Attribute value pairs to use for the updated
432
468
  # version
469
+ # @param [Bignum] cas CAS value
433
470
  # @return [Couchbase::Model] The updated object
434
- def update(attrs)
471
+ def update(attrs, cas = nil)
435
472
  update_attributes(attrs)
436
- save
473
+ save(cas)
437
474
  end
438
475
 
439
476
  # Delete this object from the bucket
@@ -442,12 +479,13 @@ module Couchbase
442
479
  #
443
480
  # @note This method will reset +id+ attribute
444
481
  #
482
+ # @param [Bignum] cas CAS value
445
483
  # @return [Couchbase::Model] Returns a reference of itself.
446
484
  #
447
485
  # @example Delete the Post model
448
486
  # p = Post.find('hello-world')
449
487
  # p.delete
450
- def delete
488
+ def delete(cas = nil)
451
489
  raise Couchbase::Error::MissingId, "missing id attribute" unless @id
452
490
  model.bucket.delete(@id)
453
491
  @id = nil
@@ -467,6 +505,11 @@ module Couchbase
467
505
  !@id
468
506
  end
469
507
 
508
+ # @return [true, false] Where on on this object persisted in the storage
509
+ def persisted?
510
+ !!@id
511
+ end
512
+
470
513
  # Check if the key exists in the bucket
471
514
  #
472
515
  # @since 0.0.1
@@ -627,8 +670,6 @@ module Couchbase
627
670
  buf
628
671
  end
629
672
 
630
- protected
631
-
632
673
  # @private Returns a hash with model attributes
633
674
  #
634
675
  # @since 0.1.0
@@ -639,6 +680,24 @@ module Couchbase
639
680
  end
640
681
  ret
641
682
  end
683
+
684
+ protected :attributes_with_values
685
+
686
+ if defined?(::Rails)
687
+ extend ActiveModel::Callbacks
688
+ define_model_callbacks :create, :update, :delete, :save
689
+ [:save, :create, :update, :delete].each do |meth|
690
+ class_eval <<-EOC
691
+ alias #{meth}_without_callbacks #{meth}
692
+ def #{meth}(*args, &block)
693
+ run_callbacks(:#{meth}) do
694
+ #{meth}_without_callbacks(*args, &block)
695
+ end
696
+ end
697
+ EOC
698
+ end
699
+ end
700
+
642
701
  end
643
702
 
644
703
  end
@@ -0,0 +1,23 @@
1
+ # Author:: Couchbase <info@couchbase.com>
2
+ # Copyright:: 2012 Couchbase, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ class String
19
+ def camelize
20
+ res = self.sub(/^[a-z\d]*/) { $&.capitalize }
21
+ res.gsub(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{$2.capitalize}" }.gsub('/', '::')
22
+ end
23
+ end
@@ -0,0 +1,29 @@
1
+ # Author:: Couchbase <info@couchbase.com>
2
+ # Copyright:: 2012 Couchbase, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ class String
19
+ def constantize
20
+ names = self.split('::')
21
+ names.shift if names.empty? || names.first.empty?
22
+
23
+ constant = Object
24
+ names.each do |name|
25
+ constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
26
+ end
27
+ constant
28
+ end
29
+ end
@@ -19,7 +19,7 @@ module Couchbase
19
19
 
20
20
  class Model
21
21
 
22
- VERSION = "0.2.0"
22
+ VERSION = "0.3.0"
23
23
 
24
24
  end
25
25
 
@@ -24,6 +24,15 @@ class Post < Couchbase::Model
24
24
  attribute :created_at, :default => lambda { Time.utc("2010-01-01") }
25
25
  end
26
26
 
27
+ class Brewery < Couchbase::Model
28
+ attribute :name
29
+ end
30
+
31
+ class Beer < Couchbase::Model
32
+ attribute :name
33
+ belongs_to :brewery
34
+ end
35
+
27
36
  class TestModel < MiniTest::Unit::TestCase
28
37
 
29
38
  def setup
@@ -103,9 +112,9 @@ class TestModel < MiniTest::Unit::TestCase
103
112
  EOC
104
113
 
105
114
  comment = Comment.new
106
- assert comment.respond_to?(:name)
107
- assert comment.respond_to?(:email)
108
- assert comment.respond_to?(:body)
115
+ assert_respond_to comment, :name
116
+ assert_respond_to comment, :email
117
+ assert_respond_to comment, :body
109
118
  end
110
119
 
111
120
  def test_allows_arbitrary_ids
@@ -152,4 +161,14 @@ class TestModel < MiniTest::Unit::TestCase
152
161
  end
153
162
  end
154
163
 
164
+ def test_belongs_to_assoc
165
+ brewery = Brewery.create(:name => "Anheuser-Busch")
166
+ assert_includes Beer.attributes.keys, :brewery_id
167
+ beer = Beer.create(:name => "Budweiser", :brewery_id => brewery.id)
168
+ assert_respond_to beer, :brewery
169
+ assoc = beer.brewery
170
+ assert_instance_of Brewery, assoc
171
+ assert_equal "Anheuser-Busch", assoc.name
172
+ end
173
+
155
174
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: couchbase-model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-18 00:00:00.000000000 Z
12
+ date: 2012-09-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: couchbase
@@ -124,6 +124,8 @@ files:
124
124
  - lib/couchbase-model.rb
125
125
  - lib/couchbase/model.rb
126
126
  - lib/couchbase/model/configuration.rb
127
+ - lib/couchbase/model/ext/camelize.rb
128
+ - lib/couchbase/model/ext/constantize.rb
127
129
  - lib/couchbase/model/ext/singleton_class.rb
128
130
  - lib/couchbase/model/uuid.rb
129
131
  - lib/couchbase/model/version.rb