Module: ActivityNotification::Association

Extended by:
ActiveSupport::Concern
Included in:
Notifiable, Notifier, ORM::Dynamoid::Notification, ORM::Dynamoid::Subscription, ORM::Mongoid::Notification, ORM::Mongoid::Subscription, Subscriber, Target
Defined in:
lib/activity_notification/orm/mongoid.rb,
lib/activity_notification/orm/dynamoid.rb,
lib/activity_notification/orm/active_record.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.belongs_to_composite_xdb_record(name, _options = {}) ⇒ Object

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



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# 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 = {}) ⇒ Object

Defines polymorphic belongs_to association with models in other database.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# 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

.filtered_by_associationMongoid::Criteria<Notificaion>

Selects filtered notifications by associated instance.

Parameters:

  • name (String)

    Association name

  • instance (Object)

    Associated instance

Returns:

  • (Mongoid::Criteria<Notificaion>)

    Database query of filtered notifications



11
# File 'lib/activity_notification/orm/mongoid.rb', line 11

scope :filtered_by_association, ->(name, instance) { where("#{name}_id" => instance.present? ? instance.id : nil, "#{name}_type" => instance.present? ? instance.class.name : nil) }

.has_many_composite_xdb_records(name, options = {}) ⇒ Object

TODO:

Add dependent option

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



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# 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 = {}) ⇒ Object

TODO:

Add dependent option

Defines polymorphic has_many association with models in other database.



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# 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 = {}) ⇒ ActiveRecord_AssociationRelation<Object>

Defines has_many association with ActivityNotification models.

Returns:

  • (ActiveRecord_AssociationRelation<Object>)

    Database query of associated model instances



17
18
19
# File 'lib/activity_notification/orm/mongoid.rb', line 17

def has_many_records(name, options = {})
  has_many_polymorphic_xdb_records name, options
end

Instance Method Details

#update(attributes) ⇒ Object

Defines update method as update_attributes method



95
96
97
98
99
100
101
102
# 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