laravel-doctrine / orm

A drop-in Doctrine ORM 2 implementation for Laravel 5+ and Lumen
http://laraveldoctrine.org
MIT License
827 stars 179 forks source link

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

Open marcosdipaolo opened 5 years ago

marcosdipaolo commented 5 years ago

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.

eigan commented 5 years ago

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;
    }
}