[英]Laravel: Complicated Eloquent Relationship - hasManyThrough or belongsToMany approach?
[英]Laravel / Eloquent - hasManyThrough - belongsToMany
我嘗試創建一個使用戶能夠加入線程的Messenger,因此我有四個表:
users
id - integer
name - string
threads
id - integer
name - string
created_at - dateTime
updated_at - dateTime
participants
user_id - integer
threads_id - integer
created_at - dateTime
updated_at - dateTime
deleted_at - dateTime
messages
id - integer
user_id - integer
thread_id - integer
text - string
created_at - dateTime
updated_at - dateTime
deleted_at - dateTime
用戶具有:
threads(){
return $this->belongsToMany(
Thread::class,
'participants',
'user_id',
'thread_id'
)
->withTimestamps()
->withPivot('thread_id', 'user_id', 'deleted_at')
->orderBy('created_at', 'desc');
}
現在,我嘗試與消息建立關系,只有加入線程后的消息才可見:
public function messagesThroughThreads()
{
$relation = $this->hasManyThrough(
Message::class,
$this->threads(),
'user_id',
'thread_id',
'id',
'id'
)
->orderBy('updated_at', 'desc');
return $relation;
}
實際上,這不是那樣工作的,我通過以下方式獲得模型:
public function messagesThroughThreads(bool $show_deleted = false)
{
$messages = collect([]);
foreach ($this->threads as $thread){
if($thread->pivot->deleted_at){
$m = $thread->messages_model()->whereBetween('messages.created_at', [$thread->pivot->deleted_at, $thread->pivot->created_at])->get();
}else{
$m = $thread->messages_model()->where('messages.created_at', '>=', $thread->pivot->created_at)->get();
}
$messages = $messages->merge($m->toArray());
}
return $messages->unique();
}
知道如何在相同條件下獲得關系實例嗎?
沒有(本機)關系可以直接訪問消息。
根據您的數據,獲取所有消息然后刪除其中一些消息可能會更快:
class Thread
{
public function messages()
{
return $this->hasMany(Message::class);
}
}
public function messagesThroughThreads(bool $show_deleted = false)
{
$this->load('threads.messages');
foreach ($this->threads as $thread) {
$m = $thread->messages->where('created_at', '<=', $thread->pivot->deleted_at)
->where('created_at', '>=', $thread->pivot->created_at);
}
您將要處理集合,因此無法使用whereBetween()
類的方法。
我創建了一個具有無限級別的HasManyThrough
關系: GitHub上的存儲庫
安裝后,您可以像這樣使用它:
class User extends Model {
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function messagesThroughThreads() {
return $this->hasManyDeep(Message::class, ['participants', Thread::class])
->whereColumn('messages.created_at', '>=', 'participants.created_at')
->where(function($query) {
$query->whereNull('participants.deleted_at')
->orWhereColumn('messages.created_at', '<=', 'participants.deleted_at');
})->orderByDesc('messages.updated_at');
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.