Module: Cequel::Record::Associations

Extended by:
ActiveSupport::Concern
Defined in:
lib/cequel/record/associations.rb

Overview

Cequel records can have parent-child relationships defined by belongs_to and has_many associations. Unlike in a relational database ORM, associations are not represented by foreign keys; instead they use CQL3’s compound primary keys. A child object’s primary key begins with it’s parent’s primary key.

In the below example, the ‘blogs` table has a one-column primary key `(subdomain)`, and the `posts` table has a two-column primary key `(blog_subdomain, permalink)`. All posts that belong to the blog with subdomain `“cassandra”` will have `“cassandra”` as their `blog_subdomain`.

Examples:

Blogs and Posts


class Blog
  include Cequel::Record

  key :subdomain, :text

  column :name, :text

  has_many :posts
end

class Post
  include Cequel::Record

  # This defines the first primary key column as `blog_subdomain`.
  # Because `belongs_to` associations implicitly define columns in the
  # primary key, it must come before any explicit key definition. For
  # the same reason, a Record class can only have a single `belongs_to`
  # declaration.
  belongs_to :blog

  # We also define an additional primary key column so that each post
  # has a unique compound primary key
  key :permalink

  column :title, :text
  column :body, :text
end

blog = Blog.new(subdomain: 'cassandra')
post = blog.posts.new(permalink: 'cequel')
post.blog_subdomain #=> "cassandra"

Since:

  • 1.0.0

Defined Under Namespace

Modules: ClassMethods

Instance Method Summary collapse

Instance Method Details

#destroyObject

Since:

  • 1.0.0



178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/cequel/record/associations.rb', line 178

def destroy(*)
  super.tap do
    self.class.child_associations.each_value do |association|
      case association.dependent
      when :destroy
        __send__(association.name).destroy_all
      when :delete
        __send__(association.name).delete_all
      end
    end
  end
end

#read_child_association(association_name, reload = false) ⇒ Object

Since:

  • 1.0.0



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/cequel/record/associations.rb', line 228

def read_child_association(association_name, reload = false)
  association = child_associations[association_name]
  ivar = association.instance_variable_name
  if !reload && instance_variable_defined?(ivar)
    return instance_variable_get(ivar)
  end

  base_scope = association.association_class
  association_record_set =
    key_values.reduce(base_scope) do |record_set, key_value|
      record_set[key_value]
    end

  instance_variable_set(
    ivar, AssociationCollection.new(association_record_set))
end

#read_parent_associationObject

Since:

  • 1.0.0



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/cequel/record/associations.rb', line 191

def read_parent_association
  ivar_name = parent_association.instance_variable_name
  if instance_variable_defined?(ivar_name)
    return instance_variable_get(ivar_name)
  end
  parent_key_values = key_values
    .first(parent_association.association_key_columns.length)
  if parent_key_values.none? { |value| value.nil? }
    clazz = parent_association.association_class
    parent = parent_key_values.reduce(clazz) do |record_set, key_value|
      record_set[key_value]
    end
    instance_variable_set(ivar_name, parent)
  end
end

#write_parent_association(parent) ⇒ Object

Since:

  • 1.0.0



207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/cequel/record/associations.rb', line 207

def write_parent_association(parent)
  unless parent.is_a?(parent_association.association_class)
    fail ArgumentError,
         "Wrong class for #{parent_association.name}; expected " \
         "#{parent_association.association_class.name}, got " \
         "#{parent.class.name}"
  end
  instance_variable_set "@#{parent_association.name}", parent
  key_column_names = self.class.key_column_names
  parent.key_attributes
    .zip(key_column_names) do |(parent_column_name, value), column_name|
      if value.nil?
        fail ArgumentError,
             "Can't set parent association " \
             "#{parent_association.name.inspect} " \
             "without value in key #{parent_column_name.inspect}"
      end
      write_attribute(column_name, value)
    end
end