Class: Couchbase::Model

Inherits:
Object show all
Includes:
ActiveModel
Defined in:
lib/couchbase/model.rb,
lib/couchbase/model/uuid.rb,
lib/couchbase/model/version.rb,
lib/couchbase/model/configuration.rb

Overview

Declarative layer for Couchbase gem

You can also let the library generate the unique identifier for you:

p = Post.create(:title => 'How to generate ID',
                :body => 'Open up the editor...')
p.id        #=> "74f43c3116e788d09853226603000809"

There are several algorithms available. By default it use ‘:sequential` algorithm, but you can change it to more suitable one for you:

class Post < Couchbase::Model
  attribute :title
  attribute :body
  attribute :draft

  uuid_algorithm :random
end

You can define connection options on per model basis:

class Post < Couchbase::Model
  attribute :title
  attribute :body
  attribute :draft

  connect :port => 80, :bucket => 'blog'
end

Since:

  • 0.0.1

    require ‘couchbase/model’

    class Post < Couchbase::Model

    attribute :title
    attribute :body
    attribute :draft
    

    end

    p = Post.new(:id => ‘hello-world’,

    :title => 'Hello world',
    :draft => true)
    

    p.save p = Post.find(‘hello-world’) p.body = “Once upon the times.…” p.save p.update(:draft => false) Post.bucket.get(‘hello-world’) #=> world”, “draft”=>false,

    #    "body"=>"Once upon the times...."
    

Defined Under Namespace

Modules: Configuration Classes: UUID

Constant Summary collapse

VERSION =
'0.1.0'
@@attributes =

Since:

  • 0.0.1

    require ‘couchbase/model’

    class Post < Couchbase::Model

    attribute :title
    attribute :body
    attribute :draft
    

    end

    p = Post.new(:id => ‘hello-world’,

    :title => 'Hello world',
    :draft => true)
    

    p.save p = Post.find(‘hello-world’) p.body = “Once upon the times.…” p.save p.update(:draft => false) Post.bucket.get(‘hello-world’) #=> world”, “draft”=>false,

    #    "body"=>"Once upon the times...."
    
{}
@@views =

Since:

  • 0.0.1

    require ‘couchbase/model’

    class Post < Couchbase::Model

    attribute :title
    attribute :body
    attribute :draft
    

    end

    p = Post.new(:id => ‘hello-world’,

    :title => 'Hello world',
    :draft => true)
    

    p.save p = Post.find(‘hello-world’) p.body = “Once upon the times.…” p.save p.update(:draft => false) Post.bucket.get(‘hello-world’) #=> world”, “draft”=>false,

    #    "body"=>"Once upon the times...."
    
{}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ActiveModel

#==, #eql?, #hash, included, #to_model

Constructor Details

#initialize(attrs = {}) ⇒ Model

Constructor for all subclasses of Couchbase::Model

Optionally takes a Hash of attribute value pairs.

Parameters:

  • attrs (Hash) (defaults to: {})

    attribute-value pairs

Since:

  • 0.0.1



482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
# File 'lib/couchbase/model.rb', line 482

def initialize(attrs = {})
  @errors = ::ActiveModel::Errors.new(self) if defined?(::ActiveModel)
  @_attributes = ::Hash.new do |h, k|
    default = self.class.attributes[k]
    h[k] = if default.respond_to?(:call)
             default.call
           else
             default
           end
  end
  case attrs
  when Hash
    if defined?(HashWithIndifferentAccess) && !attrs.is_a?(HashWithIndifferentAccess)
      attrs = attrs.with_indifferent_access
    end
    @id = attrs.delete(:id)
    @key = attrs.delete(:key)
    @value = attrs.delete(:value)
    @doc = attrs.delete(:doc)
    @meta = attrs.delete(:meta)
    @raw = attrs.delete(:raw)
    update_attributes(@doc || attrs)
  else
    @raw = attrs
  end
end

Instance Attribute Details

#docObject (readonly)

Since:

  • 0.2.0



125
126
127
# File 'lib/couchbase/model.rb', line 125

def doc
  @doc
end

#errorsObject (readonly)

Since:

  • 0.4.5



131
132
133
# File 'lib/couchbase/model.rb', line 131

def errors
  @errors
end

#idObject

Each model must have identifier

Since:

  • 0.0.1



116
117
118
# File 'lib/couchbase/model.rb', line 116

def id
  @id
end

#keyObject (readonly)

Since:

  • 0.2.0



119
120
121
# File 'lib/couchbase/model.rb', line 119

def key
  @key
end

#metaObject (readonly)

Since:

  • 0.2.0



128
129
130
# File 'lib/couchbase/model.rb', line 128

def meta
  @meta
end

#rawObject (readonly)

Since:

  • 0.4.5



134
135
136
# File 'lib/couchbase/model.rb', line 134

def raw
  @raw
end

#valueObject (readonly)

Since:

  • 0.2.0



122
123
124
# File 'lib/couchbase/model.rb', line 122

def value
  @value
end

Class Method Details

._find(quiet, *ids) ⇒ Object

Since:

  • 0.0.1

    require ‘couchbase/model’

    class Post < Couchbase::Model

    attribute :title
    attribute :body
    attribute :draft
    

    end

    p = Post.new(:id => ‘hello-world’,

    :title => 'Hello world',
    :draft => true)
    

    p.save p = Post.find(‘hello-world’) p.body = “Once upon the times.…” p.save p.update(:draft => false) Post.bucket.get(‘hello-world’) #=> world”, “draft”=>false,

    #    "body"=>"Once upon the times...."
    


403
404
405
406
407
408
409
410
411
412
413
# File 'lib/couchbase/model.rb', line 403

def _find(quiet, *ids)
  wants_array = ids.first.kind_of?(Array)
  ids = ids.flatten.compact.uniq
  unless ids.empty?
    res = bucket.get(ids, :quiet => quiet, :extended => true).map do |id, (obj, flags, cas)|
      obj = {:raw => obj} unless obj.is_a?(Hash)
      new({:id => id, :meta => {'flags' => flags, 'cas' => cas}}.merge(obj))
    end
    wants_array ? res : res.first
  end
end

.attribute(*names) ⇒ Object

Defines an attribute for the model

Examples:

Define some attributes for a model

class Post < Couchbase::Model
  attribute :title
  attribute :body
  attribute :published_at
end

post = Post.new(:title => 'Hello world',
                :body => 'This is the first example...',
                :published_at => Time.now)

Parameters:

  • name (Symbol, String)

    name of the attribute

Since:

  • 0.0.1



322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
# File 'lib/couchbase/model.rb', line 322

def self.attribute(*names)
  options = {}
  if names.last.is_a?(Hash)
    options = names.pop
  end
  names.each do |name|
    name = name.to_sym
    attributes[name] = options[:default]
    next if self.instance_methods.include?(name)
    define_method(name) do
      read_attribute(name)
    end
    define_method(:"#{name}=") do |value|
      write_attribute(name, value)
    end
  end
end

.attributesHash

All defined attributes within a class.

Returns:

  • (Hash)

See Also:

Since:

  • 0.0.1



670
671
672
673
674
675
676
# File 'lib/couchbase/model.rb', line 670

def self.attributes
  @attributes ||= if self == Model
                    @@attributes.dup
                  else
                    couchbase_ancestor.attributes.dup
                  end
end

.belongs_to(name, options = {}) ⇒ Object

Defines a belongs_to association for the model

Examples:

Define some association for a model

class Brewery < Couchbase::Model
  attribute :name
end

class Beer < Couchbase::Model
  attribute :name, :brewery_id
  belongs_to :brewery
end

Beer.find("heineken").brewery.name

Parameters:

  • name (Symbol, String)

    name of the associated model

  • options (Hash) (defaults to: {})

    association options

Options Hash (options):

  • :class_name (String, Symbol)

    the name of the association class

Since:

  • 0.3.0



393
394
395
396
397
398
399
400
# File 'lib/couchbase/model.rb', line 393

def self.belongs_to(name, options = {})
  ref = "#{name}_id"
  attribute(ref)
  assoc = name.to_s.camelize.constantize
  define_method(name) do
    assoc.find(self.send(ref))
  end
end

.bucketObject

Since:

  • 0.0.1



762
763
764
# File 'lib/couchbase/model.rb', line 762

def self.bucket
  self.thread_storage[:bucket] ||= Couchbase.bucket
end

.bucket=(connection) ⇒ Object

Parameters:

  • connection (Bucket)

    the connection instance

Since:

  • 0.0.1



771
772
773
# File 'lib/couchbase/model.rb', line 771

def self.bucket=(connection)
  self.thread_storage[:bucket] = connection
end

.connect(*options) ⇒ Couchbase::Bucket

Use custom connection options

Examples:

Choose specific bucket

class Post < Couchbase::Model
  connect :bucket => 'posts'
  ...
end

Parameters:

  • options (String, Hash, Array)

    options for establishing connection.

Returns:

  • (Couchbase::Bucket)

See Also:

  • Bucket#initialize

Since:

  • 0.0.1



157
158
159
# File 'lib/couchbase/model.rb', line 157

def self.connect(*options)
  self.bucket = Couchbase.connect(*options)
end

.couchbase_ancestorObject

Returns the first ancestor that is also a Couchbase::Model ancestor.

Returns:

  • Class

Since:

  • 0.0.1

    require ‘couchbase/model’

    class Post < Couchbase::Model

    attribute :title
    attribute :body
    attribute :draft
    

    end

    p = Post.new(:id => ‘hello-world’,

    :title => 'Hello world',
    :draft => true)
    

    p.save p = Post.find(‘hello-world’) p.body = “Once upon the times.…” p.save p.update(:draft => false) Post.bucket.get(‘hello-world’) #=> world”, “draft”=>false,

    #    "body"=>"Once upon the times...."
    


696
697
698
699
700
# File 'lib/couchbase/model.rb', line 696

def self.couchbase_ancestor
  ancestors[1..-1].each do |ancestor|
    return ancestor if ancestor.ancestors.include?(Couchbase::Model)
  end
end

.create(*args) ⇒ Couchbase::Model, false

Create the model with given attributes

Parameters:

  • args (Hash)

    attribute-value pairs for the object

Returns:

Since:

  • 0.0.1



462
463
464
# File 'lib/couchbase/model.rb', line 462

def self.create(*args)
  new(*args).create
end

.create!(*args) ⇒ Object

Creates an object just like {Model{Model.create but raises an exception if the record is invalid.

Raises:

  • (Couchbase::Error::RecordInvalid)

    if the instance is invalid

Since:

  • 0.5.1



471
472
473
# File 'lib/couchbase/model.rb', line 471

def self.create!(*args)
  new(*args).create!
end

.defaults(options = nil) ⇒ Object

Since:

  • 0.0.1

    require ‘couchbase/model’

    class Post < Couchbase::Model

    attribute :title
    attribute :body
    attribute :draft
    

    end

    p = Post.new(:id => ‘hello-world’,

    :title => 'Hello world',
    :draft => true)
    

    p.save p = Post.find(‘hello-world’) p.body = “Once upon the times.…” p.save p.update(:draft => false) Post.bucket.get(‘hello-world’) #=> world”, “draft”=>false,

    #    "body"=>"Once upon the times...."
    


195
196
197
198
199
200
201
# File 'lib/couchbase/model.rb', line 195

def self.defaults(options = nil)
  if options
    @_defaults = options
  else
    @_defaults || {}
  end
end

.design_document(name = nil) ⇒ String

Associate custom design document with the model

Design document is the special document which contains views, the chunks of code for building map/reduce indexes. When this method called without argument, it just returns the effective design document name.

Examples:

Choose specific design document name

class Post < Couchbase::Model
  design_document :my_posts
  ...
end

Parameters:

  • name (String, Symbol) (defaults to: nil)

    the name for the design document. By default underscored model name is used.

Returns:

  • (String)

    the effective design document

See Also:

Since:

  • 0.1.0



181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/couchbase/model.rb', line 181

def self.design_document(name = nil)
  if name
    @_design_doc = name.to_s
  else
    @_design_doc ||= begin
                       name = self.name.dup
                       name.gsub!(/::/, '_')
                       name.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
                       name.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
                       name.downcase!
                     end
  end
end

.ensure_design_document!Object

Ensure that design document is up to date.

This method also cares about organizing view in separate javascript files. The general structure is the following ([root] is the directory, one of the Couchbase::Model::Configuration#design_documents_paths):

[root]
|
`- link
|  |
|  `- by_created_at
|  |  |
|  |  `- map.js
|  |
|  `- by_session_id
|  |  |
|  |  `- map.js
|  |
|  `- total_views
|  |  |
|  |  `- map.js
|  |  |
|  |  `- reduce.js

The directory structure above demonstrate layout for design document with id _design/link and three views: by_create_at, +by_session_id` and ‘total_views`.

Since:

  • 0.1.0



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
# File 'lib/couchbase/model.rb', line 232

def self.ensure_design_document!
  unless Configuration.design_documents_paths
    raise 'Configuration.design_documents_path must be directory'
  end

  doc = {'_id' => "_design/#{design_document}", 'views' => {}}
  digest = Digest::MD5.new
  mtime = 0
  views.each do |name, _|
    doc['views'][name] = {}
    doc['spatial'] = {}
    ['map', 'reduce', 'spatial'].each do |type|
      Configuration.design_documents_paths.each do |path|
        ff = File.join(path, design_document.to_s, name.to_s, "#{type}.js")
        if File.file?(ff)
          contents = File.read(ff).gsub(/^\s*\/\/.*$\n\r?/, '').strip
          next if contents.empty?
          mtime = [mtime, File.mtime(ff).to_i].max
          digest << contents
          case type
          when 'map', 'reduce'
            doc['views'][name][type] = contents
          when 'spatial'
            doc['spatial'][name] = contents
          end
          break # pick first matching file
        end
      end
    end
  end

  doc['views'].delete_if {|_, v| v.empty? }
  doc.delete('spatial') if doc['spatial'] && doc['spatial'].empty?
  doc['signature'] = digest.to_s
  doc['timestamp'] = mtime
  if doc['signature'] != thread_storage[:signature] && doc['timestamp'] > thread_storage[:timestamp].to_i
    current_doc = bucket.design_docs[design_document.to_s]
    if current_doc.nil? || (current_doc['signature'] != doc['signature'] && doc['timestamp'] > current_doc[:timestamp].to_i)
      bucket.save_design_doc(doc)
      current_doc = doc
    end
    thread_storage[:signature] = current_doc['signature']
    thread_storage[:timestamp] = current_doc['timestamp'].to_i
  end
end

.exists?(id) ⇒ true, false

Check if the key exists in the bucket

Parameters:

  • id (String, Symbol)

    the record identifier

Returns:

  • (true, false)

    Whether or not the object with given id presented in the bucket.

Since:

  • 0.0.1



649
650
651
# File 'lib/couchbase/model.rb', line 649

def self.exists?(id)
  !!bucket.get(id, :quiet => true)
end

.find(*id) ⇒ Couchbase::Model, Array

Find the model using id attribute

Examples:

Find model using id

post = Post.find('the-id')

Find multiple models using id

post = Post.find('one', 'two')

Parameters:

  • id (String, Symbol, Array)

    model identificator(s)

Returns:

  • (Couchbase::Model, Array)

    an instance of the model, or an array of instances

Raises:

  • (Couchbase::Error::NotFound)

    when given key isn’t exist

Since:

  • 0.0.1



431
432
433
# File 'lib/couchbase/model.rb', line 431

def self.find(*id)
  _find(false, *id)
end

.find_by_id(*id) ⇒ Couchbase::Model, ...

Find the model using id attribute

Unlike find, this method won’t raise Error::NotFound error when key doesn’t exist in the bucket

Examples:

Find model using id

post = Post.find_by_id('the-id')

Find multiple models using id

posts = Post.find_by_id(['the-id', 'the-id2'])

Parameters:

  • id (String, Symbol)

    model identificator(s)

Returns:

  • (Couchbase::Model, Array, nil)

    an instance of the model, an array of found instances of the model, or nil if given key isn’t exist

Since:

  • 0.1.0



452
453
454
# File 'lib/couchbase/model.rb', line 452

def self.find_by_id(*id)
  _find(true, *id)
end

.inspectObject

Since:

  • 0.0.1

    require ‘couchbase/model’

    class Post < Couchbase::Model

    attribute :title
    attribute :body
    attribute :draft
    

    end

    p = Post.new(:id => ‘hello-world’,

    :title => 'Hello world',
    :draft => true)
    

    p.save p = Post.find(‘hello-world’) p.body = “Once upon the times.…” p.save p.update(:draft => false) Post.bucket.get(‘hello-world’) #=> world”, “draft”=>false,

    #    "body"=>"Once upon the times...."
    


822
823
824
825
826
827
828
# File 'lib/couchbase/model.rb', line 822

def self.inspect
  buf = "#{name}"
  if self != Couchbase::Model
    buf << "(#{['id', attributes.map(&:first)].flatten.join(', ')})"
  end
  buf
end

.thread_storageObject

Since:

  • 0.0.1



755
756
757
# File 'lib/couchbase/model.rb', line 755

def self.thread_storage
  Couchbase.thread_storage[self] ||= {:uuid_algorithm => :sequential}
end

.uuid_algorithm(algorithm) ⇒ Symbol

Choose the UUID generation algorithms

Examples:

Select :random UUID generation algorithm

class Post < Couchbase::Model
  uuid_algorithm :random
  ...
end

Parameters:

  • algorithm (Symbol)

    (:sequential) one of the available algorithms.

Returns:

  • (Symbol)

See Also:

  • UUID#next

Since:

  • 0.0.1



294
295
296
# File 'lib/couchbase/model.rb', line 294

def self.uuid_algorithm(algorithm)
  self.thread_storage[:uuid_algorithm] = algorithm
end

.view(*names) ⇒ Object

Defines a view for the model

Examples:

Define some views for a model

class Post < Couchbase::Model
  view :all, :published
  view :by_rating, :include_docs => false
end

post = Post.find("hello")
post.by_rating.each do |r|
  # ...
end

Parameters:

  • names (Symbol, String, Array)

    names of the views

  • options (Hash)

    options passed to the View

Since:

  • 0.0.1



357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
# File 'lib/couchbase/model.rb', line 357

def self.view(*names)
  options = {:wrapper_class => self, :include_docs => true}
  if names.last.is_a?(Hash)
    options.update(names.pop)
  end
  is_spatial = options.delete(:spatial)
  names.each do |name|
    path = '_design/%s/_%s/%s' % [design_document, is_spatial ? 'spatial' : 'view', name]
    views[name] = lambda do |*params|
      params = options.merge(params.first || {})
      View.new(bucket, path, params)
    end
    singleton_class.send(:define_method, name, &views[name])
  end
end

.viewsArray

All defined views within a class.

Returns:

  • (Array)

See Also:

Since:

  • 0.1.0



685
686
687
688
689
690
691
# File 'lib/couchbase/model.rb', line 685

def self.views
  @views ||= if self == Model
               @@views.dup
             else
               couchbase_ancestor.views.dup
             end
end

.wrap(bucket, data) ⇒ Model

Parameters:

  • bucket (Bucket)

    the reference to Bucket instance

  • data (Hash)

    the Hash fetched by View, it should have at least “id”, “key” and “value” keys, also it could have optional “doc” key.

Returns:

Since:

  • 0.0.1



792
793
794
795
796
797
798
799
800
801
802
803
# File 'lib/couchbase/model.rb', line 792

def self.wrap(bucket, data)
  doc = {
    :id => data['id'],
    :key => data['key'],
    :value => data['value']
  }
  if data['doc']
    doc[:meta] = data['doc']['meta']
    doc[:doc] = data['doc']['value'] || data['doc']['json']
  end
  new(doc)
end

Instance Method Details

#as_json(options = {}) ⇒ Hash

Format the model for use in a JSON response

Returns:

  • (Hash)

    a JSON representation of the model for REST APIs

Since:

  • 0.5.2



748
749
750
# File 'lib/couchbase/model.rb', line 748

def as_json(options = {})
  attributes.merge({:id => @id}).as_json(options)
end

#attributesHash

All the attributes of the current instance

Returns:

  • (Hash)

Since:

  • 0.0.1



707
708
709
# File 'lib/couchbase/model.rb', line 707

def attributes
  @_attributes
end

#create(options = {}) ⇒ Couchbase::Model, false

Create this model and assign new id if necessary

Examples:

Create the instance of the Post model

p = Post.new(:title => 'Hello world', :draft => true)
p.create

Returns:

Raises:

  • (Couchbase::Error::KeyExists)

    if model with the same id exists in the bucket

Since:

  • 0.0.1



521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
# File 'lib/couchbase/model.rb', line 521

def create(options = {})
  @id ||= Couchbase::Model::UUID.generator.next(1, model.thread_storage[:uuid_algorithm])
  if respond_to?(:valid?) && !valid?
    return false
  end
  options = model.defaults.merge(options)
  value = (options[:format] == :plain) ?  @raw : attributes_with_values
  unless @meta
    @meta = {}
    if @meta.respond_to?(:with_indifferent_access)
      @meta = @meta.with_indifferent_access
    end
  end
  @meta['cas'] = model.bucket.add(@id, value, options)
  self
end

#create!(options = {}) ⇒ Object

Creates an object just like Couchbase::Model.{Model{Model#create but raises an exception if the record is invalid.

Raises:

  • (Couchbase::Error::RecordInvalid)

    if the instance is invalid

Since:

  • 0.5.1



544
545
546
# File 'lib/couchbase/model.rb', line 544

def create!(options = {})
  create(options) || raise(Couchbase::Error::RecordInvalid.new(self))
end

#delete(options = {}) ⇒ Couchbase::Model

Note:

This method will reset id attribute

Delete this object from the bucket

Examples:

Delete the Post model

p = Post.find('hello-world')
p.delete

Parameters:

  • options (Hash) (defaults to: {})

    options for operation, see Couchbase::Model.{Couchbase{Couchbase::Bucket{Couchbase::Bucket#delete}

Returns:

Raises:

  • (Couchbase::Error::MissingId)

Since:

  • 0.0.1



616
617
618
619
620
621
622
# File 'lib/couchbase/model.rb', line 616

def delete(options = {})
  raise Couchbase::Error::MissingId, 'missing id attribute' unless @id
  model.bucket.delete(@id, options)
  @id = nil
  @meta = nil
  self
end

#exists?true, false

Check if this model exists in the bucket.

Returns:

  • (true, false)

    Whether or not this object presented in the bucket.

Since:

  • 0.0.1



659
660
661
# File 'lib/couchbase/model.rb', line 659

def exists?
  model.exists?(@id)
end

#inspectObject

of the record.

Since:

  • 0.0.1



809
810
811
812
813
814
815
816
817
818
819
820
# File 'lib/couchbase/model.rb', line 809

def inspect
  attrs = []
  attrs << ['key', @key.inspect] unless @key.nil?
  attrs << ['value', @value.inspect] unless @value.nil?
  model.attributes.map do |attr, default|
    val = read_attribute(attr)
    attrs << [attr.to_s, val.inspect] unless val.nil?
  end
  attrs.sort!
  attrs.unshift([:id, id]) unless new?
  sprintf('#<%s %s>', model, attrs.map { |a| a.join(': ') }.join(', '))
end

#modelObject

Since:

  • 0.0.1



778
779
780
# File 'lib/couchbase/model.rb', line 778

def model
  self.class
end

#new?true, false

Note:

true doesn’t mean that record exists in the database

Check if the record have id attribute

Returns:

  • (true, false)

    Whether or not this object has an id.

See Also:

Since:

  • 0.0.1



633
634
635
# File 'lib/couchbase/model.rb', line 633

def new?
  !@id
end

#persisted?true, false

Returns Where on on this object persisted in the storage.

Returns:

  • (true, false)

    Where on on this object persisted in the storage

Since:

  • 0.0.1

    require ‘couchbase/model’

    class Post < Couchbase::Model

    attribute :title
    attribute :body
    attribute :draft
    

    end

    p = Post.new(:id => ‘hello-world’,

    :title => 'Hello world',
    :draft => true)
    

    p.save p = Post.find(‘hello-world’) p.body = “Once upon the times.…” p.save p.update(:draft => false) Post.bucket.get(‘hello-world’) #=> world”, “draft”=>false,

    #    "body"=>"Once upon the times...."
    


638
639
640
# File 'lib/couchbase/model.rb', line 638

def persisted?
  !!@id
end

#read_attribute(attr_name) ⇒ Object

Since:

  • 0.0.1

    require ‘couchbase/model’

    class Post < Couchbase::Model

    attribute :title
    attribute :body
    attribute :draft
    

    end

    p = Post.new(:id => ‘hello-world’,

    :title => 'Hello world',
    :draft => true)
    

    p.save p = Post.find(‘hello-world’) p.body = “Once upon the times.…” p.save p.update(:draft => false) Post.bucket.get(‘hello-world’) #=> world”, “draft”=>false,

    #    "body"=>"Once upon the times...."
    


298
299
300
# File 'lib/couchbase/model.rb', line 298

def read_attribute(attr_name)
  @_attributes[attr_name]
end

#reloadModel

Reload all the model attributes from the bucket

Returns:

  • (Model)

    the latest model state

Raises:

Since:

  • 0.0.1



734
735
736
737
738
739
740
# File 'lib/couchbase/model.rb', line 734

def reload
  raise Couchbase::Error::MissingId, 'missing id attribute' unless @id
  pristine = model.find(@id)
  update_attributes(pristine.attributes)
  @meta[:cas] = pristine.meta[:cas]
  self
end

#save(options = {}) ⇒ Couchbase::Model, false

Create or update this object based on the state of #new?.

Examples:

Update the Post model

p = Post.find('hello-world')
p.draft = false
p.save

Use CAS value for optimistic lock

p = Post.find('hello-world')
p.draft = false
p.save('cas' => p.meta['cas'])

Parameters:

  • options (Hash) (defaults to: {})

    options for operation, see Couchbase::Model.{Couchbase{Couchbase::Bucket{Couchbase::Bucket#set}

Returns:

  • (Couchbase::Model, false)

    saved object or false if there are validation errors

Since:

  • 0.0.1



568
569
570
571
572
573
574
575
576
577
# File 'lib/couchbase/model.rb', line 568

def save(options = {})
  return create(options) unless @meta
  if respond_to?(:valid?) && !valid?
    return false
  end
  options = model.defaults.merge(options)
  value = (options[:format] == :plain) ?  @raw : attributes_with_values
  @meta['cas'] = model.bucket.replace(@id, value, options)
  self
end

#save!(options = {}) ⇒ Object

Creates an object just like Couchbase::Model.{Model{Model#save but raises an exception if the record is invalid.

Raises:

  • (Couchbase::Error::RecordInvalid)

    if the instance is invalid

Since:

  • 0.5.1



585
586
587
# File 'lib/couchbase/model.rb', line 585

def save!(options = {})
  save(options) || raise(Couchbase::Error::RecordInvalid.new(self))
end

#to_keyObject

Redefine (if exists) #to_key to use #key if #id is missing

Since:

  • 0.0.1

    require ‘couchbase/model’

    class Post < Couchbase::Model

    attribute :title
    attribute :body
    attribute :draft
    

    end

    p = Post.new(:id => ‘hello-world’,

    :title => 'Hello world',
    :draft => true)
    

    p.save p = Post.find(‘hello-world’) p.body = “Once upon the times.…” p.save p.update(:draft => false) Post.bucket.get(‘hello-world’) #=> world”, “draft”=>false,

    #    "body"=>"Once upon the times...."
    


844
845
846
847
# File 'lib/couchbase/model.rb', line 844

def to_key
  keys = [id || key]
  keys.empty? ? nil : keys
end

#to_paramObject

Since:

  • 0.0.1

    require ‘couchbase/model’

    class Post < Couchbase::Model

    attribute :title
    attribute :body
    attribute :draft
    

    end

    p = Post.new(:id => ‘hello-world’,

    :title => 'Hello world',
    :draft => true)
    

    p.save p = Post.find(‘hello-world’) p.body = “Once upon the times.…” p.save p.update(:draft => false) Post.bucket.get(‘hello-world’) #=> world”, “draft”=>false,

    #    "body"=>"Once upon the times...."
    


849
850
851
852
853
854
# File 'lib/couchbase/model.rb', line 849

def to_param
  keys = to_key
  if keys && !keys.empty?
    keys.join('-')
  end
end

#update(attrs, options = {}) ⇒ Couchbase::Model

Update this object, optionally accepting new attributes.

Parameters:

  • attrs (Hash)

    Attribute value pairs to use for the updated version

  • options (Hash) (defaults to: {})

    options for operation, see Couchbase::Model.{Couchbase{Couchbase::Bucket{Couchbase::Bucket#set}

Returns:

Since:

  • 0.0.1



598
599
600
601
# File 'lib/couchbase/model.rb', line 598

def update(attrs, options = {})
  update_attributes(attrs)
  save(options)
end

#update_attributes(attrs) ⇒ Object

Update all attributes without persisting the changes.

Parameters:

  • attrs (Hash)

    attribute-value pairs.

Since:

  • 0.0.1



716
717
718
719
720
721
722
723
724
# File 'lib/couchbase/model.rb', line 716

def update_attributes(attrs)
  if id = attrs.delete(:id)
    @id = id
  end
  attrs.each do |key, value|
    setter = :"#{key}="
    send(setter, value) if respond_to?(setter)
  end
end

#write_attribute(attr_name, value) ⇒ Object

Since:

  • 0.0.1

    require ‘couchbase/model’

    class Post < Couchbase::Model

    attribute :title
    attribute :body
    attribute :draft
    

    end

    p = Post.new(:id => ‘hello-world’,

    :title => 'Hello world',
    :draft => true)
    

    p.save p = Post.find(‘hello-world’) p.body = “Once upon the times.…” p.save p.update(:draft => false) Post.bucket.get(‘hello-world’) #=> world”, “draft”=>false,

    #    "body"=>"Once upon the times...."
    


302
303
304
# File 'lib/couchbase/model.rb', line 302

def write_attribute(attr_name, value)
  @_attributes[attr_name] = value
end