Module: Cassie::Model

Extended by:
ActiveModel::Callbacks, ActiveSupport::Concern
Includes:
ActiveModel::Model, ActiveModel::Validations, ActiveModel::Validations::Callbacks
Defined in:
lib/cassie/model.rb

Overview

This module provides a simple interface for models backed by Cassandra tables.

Cassandra is very limited in how data can be accessed efficiently so this code is intentionally not designed as a full fledged DSL with all the nifty features of ActiveRecord. Doing so will only get you into trouble when you run into the limits of Cassandra data structures.

It implements ActiveModel::Model and supports ActiveModel callbacks on :create, :update, :save, and :destroy as well as ActiveModel validations.

Example:

class Thing
  include Cassie::Model

  self.table_name = "things"
  self.keyspace = "test"
  self.primary_key = [:owner, :id]

  column :owner, :int
  column :id, :int, :as => :identifier
  column :val, :varchar, :as => :value

  ordering_key :id, :desc

  validates_presence_of :id, :value

  before_save do
    ...
  end
end

Defined Under Namespace

Modules: ClassMethods

Instance Method Summary collapse

Instance Method Details

#==(other) ⇒ Object



466
467
468
# File 'lib/cassie/model.rb', line 466

def ==(other)
  eql?(other)
end

#attributesObject

Returns a hash of column to values. Column names will be symbols.



449
450
451
452
453
454
455
# File 'lib/cassie/model.rb', line 449

def attributes
  hash = {}
  self.class.column_names.each do |name|
    hash[name] = send(name)
  end
  hash
end

#destroyObject

Delete a record and call the destroy callbacks.



440
441
442
443
444
445
446
# File 'lib/cassie/model.rb', line 440

def destroy
  run_callbacks(:destroy) do
    self.class.connection.delete(self.class.full_table_name, key_hash)
    @persisted = false
    true
  end
end

#eql?(other) ⇒ Boolean

Returns:

  • (Boolean)


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

def eql?(other)
  other.is_a?(self.class) && other.key_hash == key_hash
end

#initialize(attributes = {}) ⇒ Object



395
396
397
398
# File 'lib/cassie/model.rb', line 395

def initialize(attributes = {})
  super
  @persisted = false
end

#key_hashObject

Returns the primary key as a hash



471
472
473
474
475
476
477
# File 'lib/cassie/model.rb', line 471

def key_hash
  hash = {}
  self.class.primary_key.each do |key|
    hash[key] = self.send(key)
  end
  hash
end

#persisted?Boolean

Return true if the record has been persisted to Cassandra.

Returns:

  • (Boolean)


401
402
403
# File 'lib/cassie/model.rb', line 401

def persisted?
  @persisted
end

#persistence_ttlObject

Subclasses can override this method to provide a TTL on the persisted record.



458
459
460
# File 'lib/cassie/model.rb', line 458

def persistence_ttl
  nil
end

#save(validate: true, ttl: nil) ⇒ Object

Save a record. Returns true if the record was persisted and false if it was invalid. This method will run the save callbacks as well as either the update or create callbacks as necessary.



408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
# File 'lib/cassie/model.rb', line 408

def save(validate: true, ttl: nil)
  valid_record = (validate ? valid? : true)
  if valid_record
    run_callbacks(:save) do
      if persisted?
        run_callbacks(:update) do
          self.class.connection.update(self.class.full_table_name, values_hash, key_hash, :ttl => persistence_ttl || ttl)
        end
      else
        run_callbacks(:create) do
          self.class.connection.insert(self.class.full_table_name, attributes, :ttl => persistence_ttl || ttl)
          @persisted = true
        end
      end
    end
    true
  else
    false
  end
end

#save!Object

Save a record. Returns true if the record was saved and raises an ActiveRecord::RecordInvalid error if the record is invalid.



431
432
433
434
435
436
437
# File 'lib/cassie/model.rb', line 431

def save!
  if save
    true
  else
    raise Cassie::RecordInvalid.new(self)
  end
end