Class: CouchbaseOrm::Base

Inherits:
Object
  • Object
show all
Extended by:
ActiveModel::Callbacks, EnsureUnique, Enum, HasMany, Index, Join
Includes:
ActiveModel::Dirty, ActiveModel::Model, ActiveModel::Serializers::JSON, Associations, Persistence, Views
Defined in:
lib/couchbase-orm/base.rb

Defined Under Namespace

Classes: Metadata

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Associations

#destroy_associations!, #reset_associations

Methods included from Persistence

#delete, #destroy, #destroyed?, #new_record?, #persisted?, #reload, #save, #save!, #touch, #update, #update!, #update_attribute

Constructor Details

#initialize(model = nil, ignore_doc_type: false, **attributes) {|_self| ... } ⇒ Base

Add support for libcouchbase response objects

Yields:

  • (_self)

Yield Parameters:



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/couchbase-orm/base.rb', line 123

def initialize(model = nil, ignore_doc_type: false, **attributes)
       = .new

    # Assign default values
    @__attributes__ = ::ActiveSupport::HashWithIndifferentAccess.new({type: self.class.design_document})
    self.class.attributes.each do |key, options|
        default = options[:default]
        if default.respond_to?(:call)
            write_attribute key, default.call
        else
            write_attribute key, default
        end
    end

    if model
        case model
        when ::Libcouchbase::Response
            doc = model.value || raise('empty response provided')
            type = doc.delete(:type)
            doc.delete(:id)

            if type && !ignore_doc_type && type.to_s != self.class.design_document
                raise "document type mismatch, #{type} != #{self.class.design_document}"
            end

            .key = model.key
            .cas = model.cas

            # This ensures that defaults are applied
            super(**doc)
        when CouchbaseOrm::Base
            attributes = model.attributes
            attributes.delete(:id)
            super(**attributes)
        else
            super(**attributes.merge(Hash(model)))
        end
    else
        super(**attributes)
    end

    yield self if block_given?

    run_callbacks :initialize
end

Class Method Details

.attribute(*names, **options) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/couchbase-orm/base.rb', line 67

def attribute(*names, **options)
    @attributes ||= {}
    names.each do |name|
        name = name.to_sym

        @attributes[name] = options
        next if self.instance_methods.include?(name)

        define_method(name) do
            read_attribute(name)
        end

        define_method(:"#{name}=") do |value|
            value = yield(value) if block_given?
            write_attribute(name, value)
        end
    end
end

.attributesObject



86
87
88
# File 'lib/couchbase-orm/base.rb', line 86

def attributes
    @attributes ||= {}
end

.bucketObject



50
51
52
# File 'lib/couchbase-orm/base.rb', line 50

def bucket
    @bucket ||= Connection.bucket
end

.bucket=(bucket) ⇒ Object



46
47
48
# File 'lib/couchbase-orm/base.rb', line 46

def bucket=(bucket)
    @bucket = bucket
end

.connect(**options) ⇒ Object



42
43
44
# File 'lib/couchbase-orm/base.rb', line 42

def connect(**options)
    @bucket = ::Libcouchbase::Bucket.new(**options)
end

.exists?(id) ⇒ Boolean Also known as: has_key?

Returns:



115
116
117
# File 'lib/couchbase-orm/base.rb', line 115

def exists?(id)
    !bucket.get(id, quiet: true).nil?
end

.find(*ids, **options) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/couchbase-orm/base.rb', line 90

def find(*ids, **options)
    options[:extended] = true
    options[:quiet] ||= false

    ids = ids.flatten
    records = bucket.get(*ids, **options)

    records = records.is_a?(Array) ? records : [records]
    records.map! { |record|
        if record
            self.new(record)
        else
            false
        end
    }
    records.select! { |rec| rec }
    ids.length > 1 ? records : records[0]
end

.find_by_id(*ids, **options) ⇒ Object Also known as: []



109
110
111
112
# File 'lib/couchbase-orm/base.rb', line 109

def find_by_id(*ids, **options)
    options[:quiet] = true
    find *ids, **options
end

.uuid_generatorObject



59
60
61
# File 'lib/couchbase-orm/base.rb', line 59

def uuid_generator
    @uuid_generator ||= IdGenerator
end

.uuid_generator=(generator) ⇒ Object



63
64
65
# File 'lib/couchbase-orm/base.rb', line 63

def uuid_generator=(generator)
    @uuid_generator = generator
end

Instance Method Details

#==(other) ⇒ Object

Public: Overrides == to compare via class and entity id.

other - Another object to compare to

Returns a boolean.



250
251
252
# File 'lib/couchbase-orm/base.rb', line 250

def ==(other)
    hash == other.hash
end

#attributesObject



201
202
203
204
205
# File 'lib/couchbase-orm/base.rb', line 201

def attributes
    copy = @__attributes__.merge({id: id})
    copy.delete(:type)
    copy
end

#attributes=(attributes) ⇒ Object



207
208
209
210
211
212
# File 'lib/couchbase-orm/base.rb', line 207

def attributes=(attributes)
    attributes.each do |key, value|
        setter = :"#{key}="
        send(setter, value) if respond_to?(setter)
    end
end

#eql?(other) ⇒ Boolean

Public: Overrides eql? to use == in the comparison.

other - Another object to compare to

Returns a boolean.

Returns:



241
242
243
# File 'lib/couchbase-orm/base.rb', line 241

def eql?(other)
    self == other
end

#hashObject

Public: Hashes identifying properties of the instance

Ruby normally hashes an object to be used in comparisons. In our case we may have two techincally different objects referencing the same entity id.

Returns a string representing the unique key.



232
233
234
# File 'lib/couchbase-orm/base.rb', line 232

def hash
    "#{self.class.name}-#{self.id}-#{@__metadata__.cas}-#{@__attributes__.hash}".hash
end

#idObject

Document ID is a special case as it is not stored in the document



171
172
173
# File 'lib/couchbase-orm/base.rb', line 171

def id
    .key || @id
end

#id=(value) ⇒ Object



175
176
177
178
179
# File 'lib/couchbase-orm/base.rb', line 175

def id=(value)
    raise 'ID cannot be changed' if .cas
    attribute_will_change!(:id)
    @id = value.to_s
end

#read_attribute(attr_name) ⇒ Object Also known as: []



181
182
183
# File 'lib/couchbase-orm/base.rb', line 181

def read_attribute(attr_name)
    @__attributes__[attr_name]
end

#to_modelObject

Public: Allows for access to ActiveModel functionality.

Returns self.



222
223
224
# File 'lib/couchbase-orm/base.rb', line 222

def to_model
    self
end

#write_attribute(attr_name, value) ⇒ Object Also known as: []=



186
187
188
189
190
191
192
193
# File 'lib/couchbase-orm/base.rb', line 186

def write_attribute(attr_name, value)
    unless value.nil?
        coerce = self.class.attributes[attr_name][:type]
        value = Kernel.send(coerce.to_s, value) if coerce
    end
    attribute_will_change!(attr_name) unless @__attributes__[attr_name] == value
    @__attributes__[attr_name] = value
end