Activity log

In order to make your component compatible with the activity log, you need to follow these steps:

  1. Make your model include the Decidim::Traceable module. This will let Decidim create versions every time your model records are changed. It uses paper_trail to generate the versions.

  2. Make your commands use Decidim.traceability to create and update records. Documentation can be found in Decidim::Traceability. This should set the author of the change in your record properly.

That’s all you need to do to get it working, really. We have a default way to present logs that Just Works™. Keep reading if you want to customize how the logs for your resources look!

The default renderer

The default renderer doesn’t know many things. It knows the author, what action was done, the resource affected and the space where the resource resides. When the resource is updated it shows the diff of all the fields that have been changed, with the old and new values for each field. values are not formatted in any specific way, so you might see some weirdly formatted values on the log diff: that’s how it’s rendered from the database.

Customizing the logs for your resources

The default presenter doesn’t fulfill your needs? You might want to create your own presenter if you find yourself in one of these cases:

  • You want to show what type of resource is affected by the action log

  • The default renderer cannot find the correct field to render the resource name

  • You want to show more info

  • You want to change the order of the factors in the log sentence

  • You want to change the format of the values in the diff

Let’s go ahead and see how to create your own resource presenter.

Custom presenters should be named as Decidim::<your module name>::<log name>::<your model name>Presenter. There’s currently only one log, AdminLog. This means that if your model is Decidim::Accountability::Result, then your admin log presenter is must be Decidim::Accountability::AdminLog::ResultPresenter. You can inherit from Decidim::Log::BasePresenter for simplicity:

module Decidim
  module Accountability
    module AdminLog
      class ResultPresenter < Decidim::Log::BasePresenter
      end
    end
  end
end

Some examples with basic customization follow, although you can read the source code docs and overwrite any method you need.

Changing the action log sentence

In order to change the default sentence to something that fits better to your resource, you can overwrite the action_string method in your presenter:

module Decidim
  module Accountability
    module AdminLog
      class ResultPresenter < Decidim::Log::BasePresenter
        private

        def action_string
          case action
          when "create"
            "decidim.accountability.admin_log.result.create"
          when "update"
            "decidim.accountability.admin_log.result.update"
          end
        end
      end
    end
  end
end

This is useful to show the resource type in the sentence.

Limiting what fields get presented in the diff

By default, all changed fields are presented in the diff. In order to limit them, overwrite the diff_fields_mapping method in your custom presenter. It has to return a Hash, where keys are the name of the attributes and values are the presenters that render the attributes. Limitations: we can only show diffs for column fields, not dynamic methods, so the diff_fields_mapping only accepts column names.

In this example, we’re telling our presenter to only present the start_date as a date, the title as an i18n field, the decidim_scope_id with no particular presenter, and progress as a percentage:

module Decidim
  module Accountability
    module AdminLog
      class ResultPresenter < Decidim::Log::BasePresenter
        private

        def diff_fields_mapping
          {
            start_date: :date,
            title: :i18n,
            decidim_scope_id: :default,
            progress: :percentage
          }
        end
      end
    end
  end
end
Value types presenters

Decidim comes with some default value types presenters to be used in the diffs. They all live in Decidim::Log::ValueTypes, check the source code for the full list. These presenters are used with a symbol, but you can use your own value type presenter if you use a string:

module Decidim
  module Accountability
    module AdminLog
      class ResultPresenter < Decidim::Log::BasePresenter
        private

        def diff_fields_mapping
          {
            decidim_scope_id: "Decidim::Accountability::AdminLog::ValueTypes::MyCustomPresenter",
          }
        end
      end
    end
  end
end

Then you can write your own value presenter as:

module Decidim
  module Accountability
    module AdminLog
      module ValueTypes
        class MyCustomPresenter < Decidim::Log::Valuetypes::DefaultPresenter
          def present
            return unless value
            "My super duper value: #{value}"
          end
        end
      end
    end
  end
end

Multiple logs

Although Decidim currently only has a log for the admin section, in the future we might need an activity log for the public part. It’s easy to assume we might need to render the same data in different formats, so we need to differentiate the presenters for each log. The current system handles the case for multiple logs, although we only have one.