module Cequel::Record::Associations
Cequel
records can have parent-child relationships defined by {ClassMethods#belongs_to belongs_to} and {ClassMethods#has_many 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`.
@example 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
Public Instance Methods
destroy(*)
click to toggle source
@private
Calls superclass method
# File lib/cequel/record/associations.rb, line 177 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)
click to toggle source
# File lib/cequel/record/associations.rb, line 227 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_association()
click to toggle source
# File lib/cequel/record/associations.rb, line 190 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)
click to toggle source
# File lib/cequel/record/associations.rb, line 206 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