Closed Sufir closed 7 years ago
Using a ValueObject as a primary key isn't supported indeed.
What is your use case ?
My case something like this https://github.com/analogueorm/analogue/wiki/Basics#value-objects (but one field), I need VO for that property.
Yes I know, but can you explain the use case in the application context ? So we can see if there is a workaround.
I solve it so
final class User implements Mappable
{
/**
* @var UserIdentity
*/
private $id;
/**
* @var int
*/
private $groupId;
/**
* @var string
*/
private $phone;
/**
* @var UserStatus
*/
private $status;
/**
* @var string
*/
private $hashIdentity;
/**
* @var bool
*/
private $isActive = true;
public function __construct(UserIdentity $id, string $phone, UserGroup $group)
{
Assertion::phone($phone);
$this->id = $id;
$this->phone = $phone;
$this->groupId = $group->id();
$this->status = new UserStatus(UserStatus::NORMAL);
}
/**
* @internal
* @access private
* {@inheritdoc}
*/
public function setEntityAttributes(array $attributes)
{
$this->id = new UserIdentity($attributes['user_id']);
$this->groupId = $attributes['group_ref_id'];
$this->phone= $attributes['phone'];
$this->status = new UserStatus($attributes['status']);
$this->hashIdentity = $attributes['user_hash_id'];
$this->isActive = !!$attributes['is_active'];
}
/**
* @internal
* @access private
* {@inheritdoc}
*/
public function getEntityAttributes()
{
return [
'user_hash_id' => $this->hashIdentity,
'user_id' => $this->id->getId(),
'phone' => $this->phone,
'group_ref_id' => $this->groupId,
'status' => $this->status->getValue(),
'is_active' => $this->isActive,
];
}
}
But I think is crutch, that is mapper responsibility. Maybe can be taught his?
I think it's not impossible to do, but would add a whole layer of complexity to the mapper.
Might consider a PR on this though, if it turns out to be a nice and simple solution.
Unrelated, but just a word about the use of final
keyword.
Entities as Final classes won't be supported in 5.4
as the new lazyloading
proxies will be extending them.
Oh, about extending... how can I use mocks and proxies with repository? For example in the integration testing I'm trying:
public function myTest(IntegrationTester $I)
{
// ...
$user = Stub::make(User::class, [
'id' => function () use ($id) {
return $id;
},
]);
$result = $this->repository->remove($user);
// etc...
}
In result
[Analogue\ORM\Exceptions\EntityMapNotFoundException] No Map registered for Mock_User_84978179
Depends if you are actually hitting the database or not .
@RemiCollin yes in this test I'm checking DB too.
Maybe try to register the mocked user class for the test, by explicity binding the UserMap
to it. Not sure it would work as it could have side effect on relationships to other object.
For testing against DB, I always use the actual class, using analogue/factory
to generate quick objects, and mock any service class the object would call to.
What is analogue/factory
, can be an short example?
This tool depend from Laravel? I dont use Laravel.
[InvalidArgumentException] Unable to locate factory with name [default] [Domain\User].
$analogue = $container->get(Analogue::class);
$r = new \ReflectionObject($analogue);
$p = $r->getProperty('manager');
$p->setAccessible(true);
$manager = $p->getValue();
$factory = new \Analogue\Factory\Factory(new \Faker\Generator(), $manager);
$user = $factory->make(User::class);
It only depends on Illuminate\Database
, but it requires some bindings in the container to work properly. I guess it should be able to work if you look at how it's done in FactoryServiceProvider
.
Closing it as it's off the current topic, but feel free to open an issue on Analogue/Factory
about this if you need.
I have error with cache if using VO for identity property (PK):