module ActivityNotification::Association

Public Instance Methods

belongs_to_composite_xdb_record(name, _options = {}) click to toggle source

Defines polymorphic belongs_to association using composite key with models in other database.

# File lib/activity_notification/orm/dynamoid.rb, line 21
def belongs_to_composite_xdb_record(name, _options = {})
  association_name     = name.to_s.singularize.underscore
  composite_field = "#{association_name}_key".to_sym
  field composite_field, :string
  associated_record_field = "stored_#{association_name}".to_sym
  field associated_record_field, :raw if ActivityNotification.config.store_with_associated_records && _options[:store_with_associated_records]

  self.instance_eval do
    define_method(name) do |reload = false|
      reload and self.instance_variable_set("@#{name}", nil)
      if self.instance_variable_get("@#{name}").blank?
        composite_key = self.send(composite_field)
        if composite_key.present? && (class_name = composite_key.split(ActivityNotification.config.composite_key_delimiter).first).present?
          object_class = class_name.classify.constantize
          self.instance_variable_set("@#{name}", object_class.where(id: composite_key.split(ActivityNotification.config.composite_key_delimiter).last).first)
        end
      end
      self.instance_variable_get("@#{name}")
    end

    define_method("#{name}=") do |new_instance|
      if new_instance.nil?
        self.send("#{composite_field}=", nil)
      else
        self.send("#{composite_field}=", "#{new_instance.class.name}#{ActivityNotification.config.composite_key_delimiter}#{new_instance.id}")
        associated_record_json = new_instance.as_json(_options[:as_json_options] || {})
        # Cast Time and DateTime field to String to handle Dynamoid unsupported type error
        if associated_record_json.present?
          associated_record_json.each do |k, v|
            associated_record_json[k] = v.to_s if v.is_a?(Time) || v.is_a?(DateTime)
          end
        end
        self.send("#{associated_record_field}=", associated_record_json) if ActivityNotification.config.store_with_associated_records && _options[:store_with_associated_records]
      end
      self.instance_variable_set("@#{name}", nil)
    end

    define_method("#{association_name}_type") do
      composite_key = self.send(composite_field)
      composite_key.present? ? composite_key.split(ActivityNotification.config.composite_key_delimiter).first : nil
    end

    define_method("#{association_name}_id") do
      composite_key = self.send(composite_field)
      composite_key.present? ? composite_key.split(ActivityNotification.config.composite_key_delimiter).last : nil
    end
  end

  self._associated_composite_records.push(association_name.to_sym)
end
belongs_to_polymorphic_xdb_record(name, _options = {}) click to toggle source

Defines polymorphic belongs_to association with models in other database.

# File lib/activity_notification/orm/mongoid.rb, line 22
def belongs_to_polymorphic_xdb_record(name, _options = {})
  association_name     = name.to_s.singularize.underscore
  id_field, type_field = "#{association_name}_id", "#{association_name}_type"
  field id_field,   type: String
  field type_field, type: String
  associated_record_field = "stored_#{association_name}"
  field associated_record_field, type: Hash if ActivityNotification.config.store_with_associated_records && _options[:store_with_associated_records]

  self.instance_eval do
    define_method(name) do |reload = false|
      reload and self.instance_variable_set("@#{name}", nil)
      if self.instance_variable_get("@#{name}").blank?
        if (class_name = self.send(type_field)).present?
          object_class = class_name.classify.constantize
          self.instance_variable_set("@#{name}", object_class.where(id: self.send(id_field)).first)
        end
      end
      self.instance_variable_get("@#{name}")
    end

    define_method("#{name}=") do |new_instance|
      if new_instance.nil? then instance_id, instance_type = nil, nil else instance_id, instance_type = new_instance.id, new_instance.class.name end
      self.send("#{id_field}=", instance_id)
      self.send("#{type_field}=", instance_type)
      associated_record_json = new_instance.as_json(_options[:as_json_options] || {})
      # Cast Hash $oid field to String id to handle BSON::String::IllegalKey
      if associated_record_json.present?
        associated_record_json.each do |k, v|
          associated_record_json[k] = v['$oid'] if v.is_a?(Hash) && v.has_key?('$oid')
        end
      end
      self.send("#{associated_record_field}=", associated_record_json) if ActivityNotification.config.store_with_associated_records && _options[:store_with_associated_records]
      self.instance_variable_set("@#{name}", nil)
    end
  end
end
has_many_composite_xdb_records(name, options = {}) click to toggle source

Defines polymorphic has_many association using composite key with models in other database. @todo Add dependent option

# File lib/activity_notification/orm/dynamoid.rb, line 74
def has_many_composite_xdb_records(name, options = {})
  association_name     = options[:as] || name.to_s.underscore
  composite_field = "#{association_name}_key".to_sym
  object_name          = options[:class_name] || name.to_s.singularize.camelize
  object_class         = object_name.classify.constantize

  self.instance_eval do
    # Set default reload arg to true since Dynamoid::Criteria::Chain is stateful on the query
    define_method(name) do |reload = true|
      reload and self.instance_variable_set("@#{name}", nil)
      if self.instance_variable_get("@#{name}").blank?
        new_value = object_class.where(composite_field => "#{self.class.name}#{ActivityNotification.config.composite_key_delimiter}#{self.id}")
        self.instance_variable_set("@#{name}", new_value)
      end
      self.instance_variable_get("@#{name}")
    end
  end
end
has_many_polymorphic_xdb_records(name, options = {}) click to toggle source

Defines polymorphic has_many association with models in other database. @todo Add dependent option

# File lib/activity_notification/orm/mongoid.rb, line 61
def has_many_polymorphic_xdb_records(name, options = {})
  association_name     = options[:as] || name.to_s.underscore
  id_field, type_field = "#{association_name}_id", "#{association_name}_type"
  object_name          = options[:class_name] || name.to_s.singularize.camelize
  object_class         = object_name.classify.constantize

  self.instance_eval do
    define_method(name) do |reload = false|
      reload and self.instance_variable_set("@#{name}", nil)
      if self.instance_variable_get("@#{name}").blank?
        new_value = object_class.where(id_field => self.id, type_field => self.class.name)
        self.instance_variable_set("@#{name}", new_value)
      end
      self.instance_variable_get("@#{name}")
    end
  end
end
has_many_records(name, options = {}) click to toggle source

Defines has_many association with ActivityNotification models. @return [ActiveRecord_AssociationRelation<Object>] Database query of associated model instances

# File lib/activity_notification/orm/active_record.rb, line 8
def has_many_records(name, options = {})
  has_many name, **options
end
update(attributes) click to toggle source

Defines update method as update_attributes method

# File lib/activity_notification/orm/dynamoid.rb, line 95
def update(attributes)
  attributes_with_association = attributes.map { |attribute, value|
    self.class._associated_composite_records.include?(attribute) ?
      ["#{attribute}_key".to_sym, value.nil? ? nil : "#{value.class.name}#{ActivityNotification.config.composite_key_delimiter}#{value.id}"] :
      [attribute, value]
  }.to_h
  update_attributes(attributes_with_association)
end