Module: Fedipub::DataEntity

Extended by:
ActiveSupport::Concern
Includes:
Announceable, HandlesDeleteRequests, Likeable
Defined in:
app/models/concerns/fedipub/data_entity.rb

Overview

Model concern to include in models for which data is pushed to the Fediverse and comes from the Fediverse.

Once included, an activity will automatically be created upon

  • entity creation
  • entity updates

Also, when properly configured, a handler is registered to transform incoming objects and create/update entities accordingly.

Pre-requisites

Model should have the following methods:

  • to_activitypub_object, returning a valid ActivityPub object
  • self.from_activitypub_object, returning a hash of valid attributes from a hash of incoming data

Table needs at least:

  • t.string :federated_url, null: true, default: nil
  • `t.references :fedipub_actor, foreign_key: true, null: true, default: nil

Model must have the following attributes:

add_column :posts, :federated_url, :string, null: true, default: nil
add_reference :posts, :fedipub_actor, foreign_key: true, null: true, default: nil

Usage

Include the concern in an existing model:

class Post < ApplicationRecord
  include Fedipub::DataEntity
  acts_as_fedipub_data options

  # This will be called when a Delete activity comes for the entry. As we don't know how you want to handle it,
  # you'll have to implement the behavior yourself.
  on_fedipub_delete_requested :do_something

  # This will be called when a Undo activity comes for the entry. The easiest way to handle this case is to re-fetch
  # the entity
  on_fedipub_undelete_requested :do_something_else

  def to_activitypub_object
    Fedipub::DataTransformer::Note.to_federation self,
                                                   content: content,
                                                   name:    title
  end

  # Creates a hash of attributes from incoming Note
  def self.from_activitypub_object(hash)
    {
      title:   hash['name'] || 'A post',
      content: hash['content'],
    }
  end
end

If your model has a mechanism for soft deletion:

  • you can specify some methods names to handle it in Fedipub responses:
  • you will need to send the delete activity yourself
acts_as_fedipub_data handles: 'Note',
                       ...,
                       soft_deleted_method: :deleted?
                       soft_delete_date_method: :deleted_at

on_fedipub_delete_requested :soft_delete!
on_fedipub_undelete_requested :restore_remote_entity!

# Method you use to soft-delete entities
def soft_delete!
  update deleted_at: time.current

  send_fedipub_activity 'Delete' unless local_fedipub_entity?
end

# Method you use to restore soft-deleted entities
def restore!
  update deleted_at: nil

  if local_fedipub_entity?
    delete_activity =  Activity.find_by action: 'Delete', entity: self
    send_fedipub_activity 'Undo', entity: delete_activity, actor: fedipub_actor if delete_activity.present?
  end
end

def restore_remote_entity!
  self.deleted_at: nil
  fedipub_sync!
  save!
end

Defined Under Namespace

Modules: ClassMethods Classes: TombstonedError

Instance Method Summary collapse

Methods included from Announceable

#announce!

Methods included from Likeable

#dislike!, #like!

Instance Method Details

#federated_urlString

Computed value for the federated URL

Returns:

  • (String)


215
216
217
218
219
220
221
222
# File 'app/models/concerns/fedipub/data_entity.rb', line 215

def federated_url
  return nil unless send(fedipub_data_configuration[:should_federate_method])
  return attributes['federated_url'] if attributes['federated_url'].present?

  path_segment = Fedipub.data_entity_configuration(self)[:route_path_segment]
  url_param = Fedipub.data_entity_configuration(self)[:url_param]
  Fedipub::Engine.routes.url_helpers.server_published_url(publishable_type: path_segment, id: send(url_param))
end

#fedipub_data_configurationObject



239
240
241
# File 'app/models/concerns/fedipub/data_entity.rb', line 239

def fedipub_data_configuration
  Fedipub.data_entity_configuration(self)
end

#fedipub_sync!Object



243
244
245
246
247
248
249
250
251
252
# File 'app/models/concerns/fedipub/data_entity.rb', line 243

def fedipub_sync!
  if local_fedipub_entity?
    Rails.logger.info { "Ignored attempt to sync a local #{self.class.name}" }
    return false
  end

  object = Fediverse::Request.dereference(federated_url)

  update! self.class.from_activitypub_object(object)
end

#fedipub_tombstoned?Boolean

Returns:

  • (Boolean)


231
232
233
# File 'app/models/concerns/fedipub/data_entity.rb', line 231

def fedipub_tombstoned?
  fedipub_data_configuration[:soft_deleted_method] ? send(fedipub_data_configuration[:soft_deleted_method]) : false
end

#fedipub_tombstoned_atObject



235
236
237
# File 'app/models/concerns/fedipub/data_entity.rb', line 235

def fedipub_tombstoned_at
  fedipub_data_configuration[:soft_delete_date_method] ? send(fedipub_data_configuration[:soft_delete_date_method]) : nil
end

#local_fedipub_entity?Boolean

Check whether the entity was created locally or comes from the Fediverse

Returns:

  • (Boolean)


227
228
229
# File 'app/models/concerns/fedipub/data_entity.rb', line 227

def local_fedipub_entity?
  attributes['federated_url'].blank?
end