# File lib/loggable_activity/activity.rb, line 88 def primary_payload_attrs primary_payload ? primary_payload.attrs : {} end
class LoggableActivity::Activity
Represents one action in the activity log.
Public Class Methods
Returns a list of activities for a given actor.
# File lib/loggable_activity/activity.rb, line 155 def self.activities_for_actor(actor, limit = 20, params = { offset: 0 }) LoggableActivity::Activity.latest(limit, params).where(actor:) end
Returns the last activity.
# File lib/loggable_activity/activity.rb, line 171 def self.last(limit = 1) return latest(1).first if limit == 1 latest(limit) end
Returns a list of activities ordered by creation date.
# File lib/loggable_activity/activity.rb, line 160 def self.latest(limit = 20, params = { offset: 0 }) offset = params[:offset] || 0 LoggableActivity::Activity .all .order(created_at: :desc) .includes(:payloads) .offset(offset) .limit(limit) end
Public Instance Methods
Returns the display name for a actor. what method to use if defined in ‘/config/loggable_activity.yaml’
Example:
@activity.actor_display_name
Returns:
"Elvis Presley"
# File lib/loggable_activity/activity.rb, line 148 def actor_display_name return I18n.t('loggable.activity.deleted') if encrypted_actor_display_name.nil? LoggableActivity::Encryption.decrypt(encrypted_actor_display_name, actor_key) end
Returns an array of hashes, each representing an activity’s attributes and its associated relations. The structure and relations to include are specified in ‘config/loggable_activity.yaml’. This format is designed for UI display purposes.
Each hash in the array contains:
-
:record_type: The class name of the record.
-
:payload_type: A descriptor of the payload’s role (e.g., ‘primary_payload’ or ‘current_association’).
-
:attrs: A hash of the record’s attributes.
Example usage:
@activity.attrs
Sample return value:
[ { record_type: MODEL_NAME, payload_type: "primary_payload", attrs: { "KEY" => "VALUE", ... } }, { record_type: MODEL_NAME, payload_type: "current_association", attrs: { "KEY" => "VALUE", ... } }, ... ]
# File lib/loggable_activity/activity.rb, line 37 def attrs ordered_payloads.map do |payload| { record_type: payload.record_type, record_id: payload.record_id, payload_type: payload.payload_type, attrs: payload.attrs, path: payload.payload_route } end end
Returns the path for the activity.
Example:
@activity.path
Returns:
"/path/to/activity"
# File lib/loggable_activity/activity.rb, line 135 def path primary_payload&.route end
Returns the attributes for the primary payload, without the relations.
Example:
@activity.primary_payload_attrs
Returns:
{ "KEY_A" => "VALUE_A", "KEY_B" => "VALUE_B", ... }
Returns the display name for a record. what method to use if defined in ‘/config/loggable_activity.yaml’
Example:
@activity.record_display_name
Returns:
"David Bowie"
# File lib/loggable_activity/activity.rb, line 120 def record_display_name return I18n.t('loggable.activity.deleted') if encrypted_record_display_name.nil? LoggableActivity::Encryption.decrypt(encrypted_record_display_name, record_key) end
Returns the attributes for the relations.
Example:
@activity.relations_attrs
Returns:
[ { record_type: CLASS.NAME, record_id: INTEGER, payload_type: ENUM attrs: { "KEY_A" => "VALUE_A", "KEY_B" => "VALUE_B", ... } } ]
# File lib/loggable_activity/activity.rb, line 107 def relations_attrs attrs.filter { |p| p[:payload_type] == 'current_association' } end
Returns a hash describing the attributes of an update activity, including updated attributes for a record and any updated related attributes.
Example:
@activity.update_activity_attrs
The return value is structured as follows:
-
:update_attrs contains the attributes of the record being updated, detailing changes from previous to new values.
-
:updated_relations_attrs is an array of hashes, each representing an updated related record. Each hash details the previous and current attributes of the relation.
Example Return Structure:
{ update_attrs: { record_class: "CLASS.NAME", attrs: [{ "KEY" => { from: "OLD_VALUE", to: "NEW_VALUE" } }] }, updated_relations_attrs: [ { record_class: "CLASS.NAME", previous_attrs: { attrs: { "KEY" => "VALUE", ... } }, current_attrs: { attrs: { "KEY" => "VALUE", ... } } } ] }
# File lib/loggable_activity/activity.rb, line 72 def update_activity_attrs { update_attrs:, updated_relations_attrs: } end
Private Instance Methods
Returns the key for the actor.
# File lib/loggable_activity/activity.rb, line 224 def actor_key return nil if actor.nil? LoggableActivity::EncryptionKey.for_record(actor)&.key end
Validates that the activity has at least one payload.
# File lib/loggable_activity/activity.rb, line 231 def must_have_at_least_one_payload errors.add(:payloads, 'must have at least one payload') if payloads.empty? end
Returns payloads sorted by :payload_type.
# File lib/loggable_activity/activity.rb, line 212 def ordered_payloads payloads.order(:payload_type) end
Returns the previous association attributes.
# File lib/loggable_activity/activity.rb, line 207 def previous_associations_attrs attrs.select { |p| p[:payload_type] == 'previous_association' } end
Returns the primary payload.
# File lib/loggable_activity/activity.rb, line 189 def primary_payload ordered_payloads.find { |p| p.payload_type == 'primary_payload' } end
Returns the key for the logged record.
# File lib/loggable_activity/activity.rb, line 217 def record_key return nil if record.nil? LoggableActivity::EncryptionKey.for_record(record)&.key end
Returns the attributes for the update+payload.
# File lib/loggable_activity/activity.rb, line 180 def update_attrs update_payload_attrs = attrs.find { |p| p[:payload_type] == 'update_payload' } return nil unless update_payload_attrs update_payload_attrs.delete(:payload_type) update_payload_attrs end
Returns the attributes for the updated relations.
# File lib/loggable_activity/activity.rb, line 194 def updated_relations_attrs grouped_associations = attrs.group_by { |p| p[:record_type] } grouped_associations.map do |record_type, payloads| previous_attrs = payloads.find { |p| p[:payload_type] == 'previous_association' } current_attrs = payloads.find { |p| p[:payload_type] == 'current_association' } next if previous_attrs.nil? && current_attrs.nil? { record_type:, previous_attrs:, current_attrs: } end.compact end