I might be doing this the wrong way, but when using the new model factory system for a "belongsTo" relationship where the "owner key" is set, getKey() will be used to resolve the parent id instead of the relations owner key.
CREATE TABLE "users" ("id" integer not null primary key autoincrement, "key" varchar not null);
CREATE TABLE "posts" ("id" integer not null primary key autoincrement, "user_key" varchar not null);
class Post extends Model
{
public function user()
{
return $this->belongsTo(User::class, 'user_key', 'key');
}
}
Post::factory()->for(User::factory())->create()->user_key; // Will be 1 instead of e.g. "abc123"
Post::factory()->for(User::factory())->create()->user; // null instead of "User" object
Hey there,
Can you first please try one of the support channels below? If you can actually identify this as a bug, feel free to report back and I'll gladly help you out and re-open this issue.
Thanks!
Hey @driesvints I think this is a bug.
If the relation is not using a parent model's primary key it will indeed fail.
A possible fix would be using the ->getOwnerKeyName() to use the parent key defined in the relationship and not assume the relation is defined using a model's primary key:
~~~php
public function attributesFor(Model $model)
{
$relationship = $model->{$this->relationship}();
return $relationship instanceof MorphTo ? [
$relationship->getMorphType() => $this->factory->newModel()->getMorphClass(),
$relationship->getForeignKeyName() => $this->resolver($relationship->getOwnerKeyName()), // CHANGED
] : [
$relationship->getForeignKeyName() => $this->resolver($relationship->getOwnerKeyName()), // CHANGED
];
}
protected function resolver($key) // CHANGED
{
return function ($relationship) use ($key) { // CHANGED
if (! $this->resolved) {
return $this->resolved = $this->factory->create()->getAttribute($key); // CHANGED
}
return $this->resolved;
};
}
~~~
I didn't send a PR because getOwnerKeyName() is available only on BelongsTo and MorphTo relations. On the other relation types this code could be run on, other relation have different method name for retrieving the analog related field, such as getLocalKeyName on HasOneOrMany base relation. So I am not sure which would be the best approach to handle this.
Thanks, I'll try to take a look into this later.
Fixed in next patch release.