couchbase-model 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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