orm icon indicating copy to clipboard operation
orm copied to clipboard

Laravel, Doctrine and the use of Value Objects to model Authentication Data

Open marcosdipaolo opened this issue 6 years ago • 1 comments

Hi there. I've been trying lately the use of Doctrine along with Laravel with LaravelDoctrine.

I was happy when i found out that actually you can make the laravel auth system work with Doctrine, its Entities and all, using some of its traits with the help of the docs and this helpful article.

All good, everything works. The only thing I wanted is a Laravel Doctrine bolierplate repo to save time every time I need to start a new prioject.

But..., here's the deal. As I code i feel the need of modeling better the name, email and password, those are the users table fields, table which was set up using Fluent . What do I mean by modeling?, the use of Value objects. With them i can take care of certain specific validation if I want, hashing if i want to do it myself, etc etc.

So my UserMapping.php file would look like this:

<?php

namespace App\Infrastructure\Mappings;

use LaravelDoctrine\Fluent\EntityMapping;
use LaravelDoctrine\Fluent\Fluent;
use Src\Entities\User;
use Src\ValueObjects\Email;
use Src\ValueObjects\Name;
use Src\ValueObjects\Password;

class UserMapping extends EntityMapping
{
    public function mapFor()
    {
        return User::class;
    }

    public function map(Fluent $builder)
    {
        $builder->bigIncrements('id');
        $builder->embed(Name::class)->noPrefix();
        $builder->embeed(Password::class)->noPrefix();
        $builder->embeed(Email::class)->noPrefix();
        $builder->timestamps();
    }
}

Point is, is this posible? Is laravel auth system flexible enough? is it a good idea? (it sounds good to me). Is it a lot of work?. Question arose when yesterday i tried really quickly and didn't work out of the box. I'll be very glad if i get some opinions about this.

marcosdipaolo avatar Jul 07 '19 01:07 marcosdipaolo

The Laravel auth system requires you to implement the Illuminate\Contracts\Auth\Authenticatable. If you return proper strings instead of the value objects (or implement __toString() on the VO), then it might work I guess.

I am not into the Fluent stuff, but why cant you just validate in the setter?

class User
{
    /**
     * @var string
     */
    private $name;

    public function setName(string $name): void
    {
        // Validate $name
        if(empty($name)) {
            throw new InvalidArgumentException("Name cannot be empty");
        }

        $this->name = $name;
    }
}

eigan avatar Jul 14 '19 11:07 eigan