Activity log
In order to make your component compatible with the activity log, you need to follow these steps:
-
Make your model include the
Decidim::Traceable
module. This will let Decidim create versions every time your model records are changed. It usespaper_trail
to generate the versions. -
Make your commands use
Decidim.traceability
to create and update records. Documentation can be found inDecidim::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.