module OceanDynamo::BelongsTo::ClassMethods


Class methods

Public Instance Methods

belongs_to(target, composite_key: false) click to toggle source

Class macro to define the belongs_to relation. For example:

class Forum < OceanDynamo::Table
  dynamo_schema do
    attribute :name
    attribute :description
  end
  has_many :topics, dependent: :destroy
end

class Topic < OceanDynamo::Table

dynamo_schema(:guid) do
  attribute :title
end
belongs_to :forum
has_many :posts, dependent: :destroy

end

class Post < OceanDynamo::Table

dynamo_schema(:guid) do
  attribute :body
end
belongs_to :topic, composite_key: true

end

The only non-standard aspect of the above is composite_key: true, which is required as the Topic class itself has a belongs_to relation and thus has a composite key. This must be declared in the child class as it needs to know how to retrieve its parent. If you were to add a Comment class to the above with a has_many/belongs_to relation to Post, the Comment class would also have a belongs_to :post, composite_key: true statement, since Post already has a composite key due to its belongs_to relation to the Topic class.

# File lib/ocean-dynamo/associations/belongs_to.rb, line 52
def belongs_to(target, composite_key: false)       # :master, "master", Master
  target_attr = target.to_s.underscore             # "master"
  target_attr_id = "#{target_attr}_id"             # "master_id"
  class_name = target_attr.classify                # "Master"
  define_class_if_not_defined(class_name)
  target_class = class_name.constantize            # Master

  assert_only_one_belongs_to!
  assert_range_key_not_specified!
  assert_hash_key_is_not_id!

  self.table_range_key = table_hash_key            # The RANGE KEY is variable
  self.table_hash_key = target_attr_id.to_sym      # The HASH KEY is the parent UUID

  attribute table_hash_key, :string                # Define :master_id
  define_attribute_accessors(table_hash_key)       # Define master_id, master_id=, master_id?

  # Make sure there always is a parent
  validates(table_hash_key, presence: true)        # Can't save without a parent_id

  # Define the range attribute (our unique UUID)
  attribute(table_range_key, :string, default: "") # Define :uuid
  define_attribute_accessors(table_range_key)      # define uuid, uuid=, uuid?


  # Define the parent id attribute
  attribute target_attr_id, :reference, default: nil, target_class: target_class,
                            association: :belongs_to
  register_relation(target_class, :belongs_to)


  # Define accessors for instances
  self.class_eval "def #{target_attr}
                     @#{target_attr} ||= load_target_from_id('#{target_attr_id}', #{composite_key})
                   end"

  self.class_eval "def #{target_attr_id}
                     read_attribute('#{target_attr_id}')
                   end"

  self.class_eval "def #{target_attr}=(value) 
                     target, target_id = type_check_target(#{target_class}, value, #{composite_key})
                     write_attribute('#{target_attr_id}', target_id) 
                     @#{target_attr} = target
                     value
                   end"

  self.class_eval "def #{target_attr_id}=(value)
                     type_check_foreign_key('#{target_attr_id}', value)
                     write_attribute('#{target_attr_id}', value) 
                     @#{target_attr} = nil
                     value
                   end"

  # Define parent builders
  self.class_eval "def self.build_#{target_attr}(**opts)
                     #{target_class}.new(opts)
                   end"

  self.class_eval "def self.create_#{target_attr}(**opts)
                     #{target_class}.create(opts)
                   end"
end
belongs_to_class() click to toggle source

Returns the class of the belongs_to association, or false if none.

# File lib/ocean-dynamo/associations/belongs_to.rb, line 129
def belongs_to_class
  has_belongs_to? && fields[table_hash_key]['target_class']
end
has_belongs_to?() click to toggle source

Returns true if the class has a belongs_to association.

# File lib/ocean-dynamo/associations/belongs_to.rb, line 120
def has_belongs_to?
  fields[table_hash_key]['association'] == :belongs_to
end