Closed yakoffka closed 1 year ago
Hi @yakoffka, Please provide the whole exception with its stacktrace. How are you using the relationship when you get this error?
Strictly speaking, I have a slightly different relations: User{id} → has many → ChatGroup{uuid, user_id} → has many → Chat{uuid, chat_group_uuid} → has many → Post{uuid, chat_uuid}
I was able to describe all connections except $chat->user(). The error occurs in tinker:
TypeError: App\Models\Chats\Chat::hasOneDeepFromReverse(): Argument #1 ($relation) must be of type Staudenmeir\EloquentHasManyDeep\HasManyDeep, Illuminate\Database\Eloquent\Relations\BelongsTo given, called in /var/www/app/Models/Chats/Chat.php on line 137
on 137 line return $this->hasOneDeepFromReverse((new ChatGroup())->user());
(new ChatGroup())->user() return BelongsTo
But, as far as I understand, the receipt scheme is similar. How to get the relation in your example for $post->country()? Is the example that I described in the first post working?
App\Models\Chats\Chat::hasOneDeepFromReverse(): Argument #1 ($relation) must be of type Staudenmeir\EloquentHasManyDeep\HasManyDeep, Illuminate\Database\Eloquent\Relations\BelongsTo given, called in /var/www/app/Models/Chats/Chat.php on line 137 {"exception":"[object] (TypeError(code: 0): App\Models\Chats\Chat::hasOneDeepFromReverse(): Argument #1 ($relation) must be of type Staudenmeir\EloquentHasManyDeep\HasManyDeep, Illuminate\Database\Eloquent\Relations\BelongsTo given, called in /var/www/app/Models/Chats/Chat.php on line 137 at /var/www/vendor/staudenmeir/eloquent-has-many-deep/src/Eloquent/Traits/ReversesRelationships.php:29) [stacktrace]
"}
/var/www/app/Models/Chats/Chat.php on line 137
What exactly does this line look like? It sounds like you defined a (incorrect) return type ...(): BelongsTo
.
BelongsTo defined in ChatGroup model:
class ChatGroup extends Model
{
...
/**
* @return HasManyDeep
* см. https://github.com/staudenmeir/eloquent-has-many-deep
*/
public function posts(): HasManyDeep
{
return $this->hasManyDeep(Post::class, [Chat::class]);
}
/**
* @return BelongsTo
*/
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
...
}
And here is the code from the model Chat:
class Chat extends Model
{
...
/**
* @return BelongsTo
*/
public function group(): BelongsTo
{
return $this->belongsTo(
ChatGroup::class,
'chat_group_uuid',
'uuid'
);
}
/**
* @return HasMany
*/
public function posts(): HasMany
{
return $this->hasMany(
Post::class,
'chat_uuid',
'uuid'
);
}
/**
* User → has many → ChatGroup → has many → Chat → has many → Post
*/
public function user()
{
return $this->hasOneDeepFromReverse((new ChatGroup())->user()); // line 137
}
...
}
in the User model, the inverse relationship is defined
class User extends Model
{
...
/**
* @return HasMany
*/
public function chatGroups(): HasMany
{
return $this->hasMany(
ChatGroup::class,
'user_id',
'id',
);
}
...
}
Argument #1 ($chatGroup->user()) for $chat->hasOneDeepFromReverse() and truth has a type BelongsTo, but it must be of this type, since this is the inverse relation of HasMany ($user->chatGroup())
I would just like to see a working example of getting a relation $post->country for your example (Country → has many → User → has many → Post → has many → Comment).
class Post extends Model
{
public function country()
{
return $this->hasOneDeepFromReverse((new User())->country());
}
}
If you get this connection without any problems, then the error is hiding somewhere in my code.
I think I figured it out: in this case, you need to use the BelongsToThrough relation
Indeed the BelongsToThrough relation helped. I suffered a little with the indication of custom keys, but it all worked.
class Chat extends Model
{
/**
* Пользователь, которому принадлежит группа данного чата (Chat -> User)
*
* User{id} → has many → ChatGroup{uuid, user_id}
* → has many → Chat{uuid, chat_group_uuid}
* → has many → Post{uuid, chat_uuid}t
*/
public function user(): BelongsToThrough
{
return $this->belongsToThrough(
User::class,
ChatGroup::class,
'chat_group_uuid', // локальный ключ в таблице chats
null,
[
ChatGroup::class => 'chat_group_uuid', // внешний ключ в таблице chats
User::class => 'user_id', // внешний ключ в таблице chat_groups
]
);
}
}
Thanks again for the package!
Hello. Thank you for a wonderful and necessary package. But I can't figure out how to get the $post->country relation:
Consider this example from the Laravel documentation with an additional level: Country → has many → User → has many → Post → has many → Comment
return error: Expected parameter of type '\Staudenmeir\EloquentHasManyDeep\HasManyDeep', '\Illuminate\Database\Eloquent\Relations\BelongsTo' provided
Can you please tell me how to describe this relationship?