module OceanDynamo::BelongsTo::ClassMethods
Class methods
Public Instance Methods
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
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
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