Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
169 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# frozen_string_literal: true | ||
|
||
module Decidim | ||
# This class wraps the logic to trace resource changes and their authorship. | ||
# It is expected to be used with classes implementing the `Decidim::Traceable` | ||
# concern. Version authors can be retrieved using the methods in | ||
# `Decidim::TraceabilityHelper`. | ||
# | ||
# Examples: | ||
# | ||
# # consider MyResource implements Decidim::Traceable | ||
# resource = Decidim::Traceability.new.create!(MyResource, author, params) | ||
# resource.versions.count # => 1 | ||
# resource.versions.last.whodunnit # => author.to_gid.to_s | ||
# resource.versions.last.event # => "create" | ||
# resource = Decidim::Traceability.new.update!(resource, author, params) | ||
# resource.versions.count # => 2 | ||
# resource.versions.last.event # => "update" | ||
# | ||
# This class uses the `paper_trail` gem internally, so refer to its documentation | ||
# for further info on how to interact with versions. | ||
class Traceability | ||
# Calls the `create` method to the given class and sets the author of the version. | ||
# | ||
# klass - An ActiveRecord class that implements `Decidim::Traceable` | ||
# author - An object that implements `to_gid` or a String | ||
# params - a Hash | ||
# | ||
# Returns an instance of `klass`. | ||
def create(klass, author, params) | ||
PaperTrail.whodunnit(gid(author)) do | ||
klass.create(params) | ||
end | ||
end | ||
|
||
# Calls the `create!` method to the given class and sets the author of the version. | ||
# | ||
# klass - An ActiveRecord class that implements `Decidim::Traceable` | ||
# author - An object that implements `to_gid` or a String | ||
# params - a Hash | ||
# | ||
# Returns an instance of `klass`. | ||
def create!(klass, author, params) | ||
PaperTrail.whodunnit(gid(author)) do | ||
klass.create!(params) | ||
end | ||
end | ||
|
||
# Updates the `resource` with `update_attributes!` and sets the author of the version. | ||
# | ||
# resource - An ActiveRecord instance that implements `Decidim::Traceable` | ||
# author - An object that implements `to_gid` or a String | ||
# params - a Hash | ||
# | ||
# Returns the updated `resource`. | ||
def update!(resource, author, params) | ||
PaperTrail.whodunnit(gid(author)) do | ||
resource.update_attributes!(params) | ||
resource | ||
end | ||
end | ||
|
||
private | ||
|
||
# Calculates the GlobalID of the version author. If the object does not respond to | ||
# `to_gid`, then it returns the object itself. | ||
def gid(author) | ||
return if author.blank? | ||
return author.to_gid if author.respond_to?(:to_gid) | ||
author | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# frozen_string_literal: true | ||
|
||
require "active_support/concern" | ||
|
||
module Decidim | ||
# A concern that adds traceabilty capability to the given model. Including this | ||
# allows you the keep track of changes in the model attributes and changes authorship. | ||
# | ||
# Example: | ||
# | ||
# class MyModel < ApplicationRecord | ||
# include Decidim::Traceable | ||
# end | ||
module Traceable | ||
extend ActiveSupport::Concern | ||
|
||
included do | ||
has_paper_trail | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# frozen_string_literal: true | ||
|
||
require "spec_helper" | ||
|
||
describe Decidim::Traceability, versioning: true do | ||
let!(:user) { create :user } | ||
let(:klass) { Decidim::DummyResources::DummyResource } | ||
let(:params) { attributes_for(:dummy_resource) } | ||
subject { described_class.new } | ||
|
||
describe "create" do | ||
it "calls `create` to the class" do | ||
expect(klass).to receive(:create).with(params) | ||
subject.create(klass, user, params) | ||
end | ||
|
||
it "generates a new version for the resource" do | ||
resource = subject.create(klass, user, params) | ||
expect(resource.versions.count).to eq 1 | ||
expect(resource.versions.last.event).to eq "create" | ||
end | ||
|
||
it "sets the author of the version to the user" do | ||
resource = subject.create(klass, user, params) | ||
expect(resource.versions.last.whodunnit).to eq user.to_gid.to_s | ||
end | ||
end | ||
|
||
describe "create!" do | ||
it "calls `create!` to the class" do | ||
expect(klass).to receive(:create!).with(params) | ||
subject.create!(klass, user, params) | ||
end | ||
|
||
it "generates a new version for the resource" do | ||
resource = subject.create!(klass, user, params) | ||
expect(resource.versions.count).to eq 1 | ||
expect(resource.versions.last.event).to eq "create" | ||
end | ||
|
||
it "sets the author of the version to the user" do | ||
resource = subject.create!(klass, user, params) | ||
expect(resource.versions.last.whodunnit).to eq user.to_gid.to_s | ||
end | ||
end | ||
|
||
describe "update!" do | ||
let(:dummy_resource) { create :dummy_resource } | ||
|
||
it "calls `update_attributes!` to the resource" do | ||
expect(dummy_resource).to receive(:update_attributes!).with(params) | ||
subject.update!(dummy_resource, user, params) | ||
end | ||
|
||
it "generates a new version for the resource" do | ||
resource = subject.update!(dummy_resource, user, params) | ||
expect(resource.versions.count).to eq 2 | ||
expect(resource.versions.last.event).to eq "update" | ||
end | ||
|
||
it "sets the author of the version to the user" do | ||
resource = subject.update!(dummy_resource, user, params) | ||
expect(resource.versions.last.whodunnit).to eq user.to_gid.to_s | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters