在我的应用程序中,我有3个模型User
,Announcement
和Like
。用户可以通过以下关系喜欢公告。
公告模型
/**
* Get the users that have liked this article
*
* @return void
*/
public function likes()
{
return $this->morphToMany(User::class, 'likeable');
}
类似模型
/**
* Get all of the announcements that are assigned this like.
*/
public function announcements()
{
return $this->morphedByMany(Announcement::class, 'likeable');
}
在LikeController
中使用几种方法来处理录制点赞。
/**
* Handle the liking of an announcements by passing in the class and ID of the model instance
*
* @param int $id
* @return void
*/
public function likeAnnouncement($id)
{
// here you can check if product exists or is valid or whatever
$this->handleLike(Announcement::class, $id);
return redirect()->back();
}
/**
* Handle a Like
* First we check the existing Likes as well as the currently soft deleted likes.
* If this Like doesn't exist, we create it using the given fields
*
* @param [type] $type
* @param [type] $id
* @return void
*/
public function handleLike($type, $id)
{
$existing_like = Like::whereLikeableType($type)
->whereLikeableId($id)
->whereUserId(Auth::user()->id)
->first();
if (is_null($existing_like)) {
// This user hasn't liked this thing so we add it
Like::create([
'user_id' => Auth::user()->id,
'likeable_id' => $id,
'likeable_type' => $type,
]);
} else {
// As existingLike was not null we need to effectively un-like this thing
$existing_like->delete();
}
}
在索引刀片中,我显示公告以及喜欢"this announcement was liked by you and 12 others"
这样的语句的人
@foreach($announcements as $key => $announcement)
<div class="announcements__item">
<p class="mb-0"><a class="announcements__item-header d-block" href="#" data-toggle="modal" data-target="#announcement{{$key}}">{{ $announcement->message }}</a></p>
<small class="announcements__item-meta d-block">Posted {{$announcement->published_at->diffForHumans()}} |
<span class="highlight-pink">{{ $announcement->user->full_name }}</span> |
<a title="{{$announcement->user_has_liked ? "Unlike this announcement" : "Like this announcement"}}" class="ml-2 announcements__item-like-btn @if($announcement->user_has_liked) liked @endif" href="" data-id="{{$announcement->id}}"><i class="fas fa-thumbs-up"></i></a>
<span class="ml-1" style="display: none;">Updating...</span>
</small>
{{-- If this is only liked by the current user --}}
@if($announcement->likes_count === 1 && $announcement->user_has_liked)
<small class="mb-0 announcements__item-like-text d-block">You liked this.</small>
@endif
{{-- If this is liked by 1 other user and not the current user --}}
@if($announcement->likes_count_excluding_auth_user === 1 && !$announcement->user_has_liked)
<small class="mb-0 announcements__item-like-text d-block">{{$announcement->random_user_who_liked_this->full_name}} liked this.</small>
@endif
{{-- If this is liked by other users and NOT the current user --}}
@if($announcement->likes_count > 1 && !$announcement->user_has_liked)
<small class="mb-0 announcements__item-like-text d-block">{{$announcement->random_user_who_liked_this->full_name}} and <span id="announcement_{{$announcement->id}}" data-likes="{{$announcement->likes_count_excluding_auth_user}}" class="announcements__item-likes">{{$announcement->likes_count_excluding_auth_user}}</span> other colleagues liked this.</small>
@endif
{{-- If this is liked by 1 other user and the current user --}}
@if($announcement->likes_count_excluding_auth_user === 1 && $announcement->user_has_liked)
<small class="mb-0 announcements__item-like-text d-block">You and {{$announcement->random_user_who_liked_this->full_name}} liked this.</small>
@endif
{{-- If this is liked by other users and the current user --}}
@if($announcement->likes_count_excluding_auth_user > 1 && $announcement->user_has_liked)
<small class="mb-0 announcements__item-like-text d-block">You, {{$announcement->random_user_who_liked_this->full_name}} and <span id="announcement_{{$announcement->id}}" data-likes="{{$announcement->likes_count_excluding_auth_user}}" class="announcements__item-likes">{{$announcement->likes_count_excluding_auth_user}}</span> other colleagues liked this.</small>
@endif
</div>
@endforeach
在Announcement
模型中,我有各种访问器:
/**
* Get the users that have liked this article
*
* @return void
*/
public function likes()
{
return $this->morphToMany(User::class, 'likeable');
}
/**
* Check if the user has liked this announcement
*
* @return void
*/
public function getUserHasLikedAttribute()
{
$like = $this->likes()->whereUserId(auth()->user()->id)->first();
return (!is_null($like)) ? true : false;
}
/**
* Get the users that have liked this article
*
* @return void
*/
public function getLikesCountAttribute()
{
return $this->likes()->count();
}
/**
* Get count of users who liked the announcement excluding the logged in user
*
* @return void
*/
public function getLikesCountExcludingAuthUserAttribute()
{
return $this->likes()->where('username', '<>', auth()->user()->username)->count();
}
/**
* Get random user who liked this announcement
*
* @return void
*/
public function getRandomUserWhoLikedThisAttribute()
{
return $this->likes()->where('username', '<>', auth()->user()->username)->inRandomOrder()->first();
}
/**
* Get all users who liked this announcement
*
* @return void
*/
public function getUsersWhoLikedThisAttribute()
{
return $this->likes()->where('username', '<>', auth()->user()->username)->get();
}
这些访问者将执行以下操作:
我要实现什么目标?
根据不同的情况,我想显示以下内容:
我提供的内容在一定程度上是行得通的,但是,由于此段运行了100多个查询,因此在任何地方都可以使用计数,有没有办法我可以缩小规模?
答案 0 :(得分:0)
您的likes
关系是否热切?如果是这样(甚至可能不是这样),您可以用急切加载的集合的计数/过滤替换其他查询。
即$this->likes->count()
而非likes()->count()
与此类似的事情是检查用户是否喜欢,而不是通过查询来检查。
public function getUserHasLikedAttribute()
{
return ! $this->likes
->filter(function ($like) {
return $like->user_id === auth()->user()->id;
})
->isEmpty();
}
显然,如果您期望非常大的数据集,那么这可能是个问题,但这是另一种选择。