Introduction
In July 2024, I started building a "Redactable Models" package to help with redacting sensitive fields in Laravel models.
Unfortunately, I didn't have any time to work on it and get it to a stable release... until recently! A couple of weeks ago, I finally got around to adding some missing features and releasing v1.0.
In this post, I'll give a brief overview of what's new in v1.0.
What is the "Redactable Models" Package?
Redactable Models is a Laravel package that allows you to easily redact sensitive fields in your Eloquent models. This is particularly useful for things like GDPR compliance and data security, where you might need to keep rows in your database, but need to remove sensitive (or personal) data.
It's a feature I've had to build several times in the past. So I thought it would be a good idea to bundle it up into a package that I (and others) could use in future projects.
As a basic example, let's say you want to specify that any user created more than 30 days ago should have their name and email redacted. You could do this by implementing the AshAllenDesign\RedactableModels\Interfaces\Redactable
interface on your User
model, and defining the redactable
and redactionStrategy
methods:
app/Models/User.php
1use AshAllenDesign\RedactableModels\Support\Strategies\ReplaceContents;2use AshAllenDesign\RedactableModels\Interfaces\Redactable;3use Illuminate\Contracts\Database\Eloquent\Builder;45class User extends Model implements Redactable6{7 // ...89 /**10 * Return a query that defines which models are eligible for redaction.11 */12 public function redactable(): Builder13 {14 return static::query()->where('created_at', '<', now()->subDays(30));15 }1617 /**18 * Return the redaction strategy to be used when redacting the model.19 */20 public function redactionStrategy(): RedactionStrategy21 {22 return app(ReplaceContents::class)->replaceWith([23 'name' => 'REDACTED',24 'email' => 'redacted@redacted.com',25 ]);26 }27}
We can then run the redaction process using an Artisan command (either manually or via a scheduled task):
1php artisan model:redact
After this command, any users created more than 30 days ago will have their name
set to REDACTED
and their email
set to redacted@redacted.com
.
If you'd like to learn more about the package, check out my blog post: Redact Model Fields in Laravel.
Or, visit the GitHub repository: github.com/ash-jc-allen/redactable-models.
Alternatively, you can check out this video I recorded from when I first released v0.1 of the package:
What's New in v1.0?
Now let's take a look at what's new in v1.0 of the package.
Mass Redaction Support
Previously, models would be redacted one at a time. This involved fetching the rows from the database, hydrating them into Eloquent models, and then redacting them one by one. For small datasets, this is completely fine and actually gives you more flexibility. For example, you could listen to the package's events or define custom redaction logic.
However, for larger datasets, this can be quite slow and inefficient, especially if you don't need any of the extra flexibility. So as of v1.0, you can now use the "mass redaction" feature. This allows you to redact models in bulk, using a single SQL UPDATE
statement without needing to retrieve any rows from the database. As you'd imagine, this is much faster for large datasets.
Let's take a look at an example of how to use mass redaction. We'll use our example code snippet from above, and update it to use mass redaction:
app/Models/User.php
1use AshAllenDesign\RedactableModels\Support\Strategies\ReplaceContents;2use AshAllenDesign\RedactableModels\Interfaces\MassRedactable;3use Illuminate\Contracts\Database\Eloquent\Builder;45class User extends Model implements MassRedactable6{7 // ...89 /**10 * Return a query that defines which models are eligible for redaction.11 */12 public function massRedactable(): Builder13 {14 return static::query()->where('created_at', '<', now()->subDays(30));15 }1617 /**18 * Return the redaction strategy to be used when redacting the model.19 */20 public function redactionStrategy(): RedactionStrategy21 {22 return app(ReplaceContents::class)->replaceWith([23 'name' => 'REDACTED',24 'email' => 'redacted@redacted.com',25 ]);26 }27}
As we can see in the code above, we've defined that the model implements the AshAllenDesign\RedactableModels\Interfaces\MassRedactable
interface. We've also defined the massRedactable
method instead of the redactable
method. This method should return a query that defines which models are eligible for redaction.
And that's it! When we run the php artisan model:redact
command, the package will now redact the models in bulk using a single SQL UPDATE
statement. The output will look like tso:
1❯ art model:redact23INFO Mass redacting [203] [App\Models\User] models.
Huge thank you to Jon Purvis for helping me with this feature, too. I appreciate the contribution!
Dependency Changes
There were also some small Composer dependency changes in v1.0.
Laravel support:
- Added support for Laravel 12.
- Dropped support for Laravel 10.
PHP support:
- Added support for PHP 8.4.
- Dropped support for PHP 8.2.
PHPUnit support:
- Added support for PHPUnit 12.
Larastan support:
- Migrated from
nunomaduro/larastan
tolarastan/larastan
.
Conclusion
I'm super excited to have finally released v1.0 of the Redactable Models package. It's something I've wanted to release for a while, so I'm glad to have finally got it over the line. I'm looking forward to using it in some of my own projects and seeing how others use it too.
If you enjoyed reading this post, you might be interested in checking out my 220+ page ebook "Battle Ready Laravel" which covers similar topics in more depth.
Or, you might want to check out my other 440+ page ebook "Consuming APIs in Laravel" which teaches you how to use Laravel to consume APIs from other services.
If you're interested in getting updated each time I publish a new post, feel free to sign up for my newsletter below.
Keep on building awesome stuff! 🚀