laravel-activitylog: Deep Diff checking is not working

When using a package like spatie’s own schemaless-attributes, the extra attributes are logged as being different every touch of the model, which not only generates useless logs even when using $logOnlyDirty but just creates confusion in the activity log itself. While specifying specific json attributes is supported, that functionality isn’t carried over into the dirty checks to confirm that what’s going into the activity log is only specifically changed json attributes. Additionally, the reverse filtering that normally works isn’t applied either (being able to set logAttributes = *, and then exclude attributes from ever being logged).

It seems that there was quite a bit more that needed to be done to add json attribute logging that what’s currently there. On top of that, in enabling that functionality or really handling any deep diffing is completely unsupported.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 17 (8 by maintainers)

Most upvoted comments

I actually had a completely different approach here, that might end up resolving the issue (maybe?) much simpler than recursion or having to denote nested keys.

Instead of treating json as json, why not just convert the properties of the model to dot notated versions, then run the diff check as is, then un-dot them. This would effectively treat the entire property set as a single level key object and prevent any recursion.

So for example, a model using extra attributes would have an array of properties on top of the model properties: (yes I know this is bad practice and you would never use schemaless attributes in this way because oh boy it’s bad, but off the top of my head here it is)

Book: ‘pages’ => 42 ‘title’ => ‘The Book’; ‘isbn’ => 12345678900, ‘extraAttributes’ => [ ‘price’ => 43, ‘author’ => [ ‘name’ => ‘Mark Twain’, ‘age’ => 31, ], ]

So normally you’d potentially have to recursively check diff on 3 levels to actually achieve what is being wanted here. Instead using Arr::dot, you’d wind up with a single level property set like: Book: ‘pages’ => 42 ‘title’ => ‘The Book’; ‘isbn’ => 12345678900, ‘extraAttributes.price’ => 43, ‘extraAttributes.author.name’ => ‘Mark Twain’, ‘extraAttributes.author.age’ => 31,

After the diff checking, you just undot the properties and bob’s your uncle! In this way the only sort of trouble added is just to dot and undot the properties before and after comparison.

Here’s an example undot macro as well:

        Arr::macro('undot', function ($arrayDot) {
            $array = [];
            foreach ($arrayDot as $key => $value) {
                Arr::set($array, $key, $value);
            }

            return $array;
        });

I think it’s a rather elegant solution if I don’t say so myself 😉

There’s probably something I’m not thinking of, but this way would make potentially a non-breaking change, and would potentially require no additional properties or configuration to put in place.