我是Laravel的初学者。我在Laravel 5.8中进行项目。我有2个表格:用户和评论。每个评论都有一个评分。一个用户可以有很多评论。
我有此代码:
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('email', 120)->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
......
$table->rememberToken();
$table->timestamps();
$table->engine = "InnoDB";
$table->charset = 'utf8mb4';
$table->collation = 'utf8mb4_unicode_ci';
});
Schema::create('comments', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->string('commentable_type');
$table->bigInteger('commentable_id');
$table->char('enable', 1)->default(0);
$table->char('to_stats', 1)->default(0);
$table->tinyInteger('rating')->default(0);
$table->text('content');
$table->dateTime('date_time');
$table->ipAddress('ip');
$table->engine = "InnoDB";
$table->charset = 'utf8mb4';
$table->collation = 'utf8mb4_unicode_ci';
});
class Comment extends Model
{
use scopeActiveTrait;
protected $quarded = ['id'];
protected $fillable = ['content', 'enable', 'rating', 'user_id', 'commentable_type', 'commentable_id', 'date_time', 'ip'];
public $timestamps = false;
public function commentable()
{
return $this->morphTo(); // typ komentowanego obiektu
}
public function user()
{
return $this->belongsTo('App\User');
}
}
class User extends Authenticatable implements MustVerifyEmail
{
use Notifiable;
use psCMS\Presenters\UserPresenter;
use scopeActiveTrait;
public static $roles = [];
public $dates = ['last_activity'];
protected $fillable = [.......];
protected $hidden = [
'password', 'remember_token',
];
// Show paid and active users
public function scopeUserAvailable($query)
{
return $query->active()
->where('email_verified_at', '<>', null)
}
public function roles()
{
return $this->belongsToMany('App\Role');
}
public function mainRole()
{
return $this->hasOne('App\Role');
}
public function comments()
{
return $this->hasMany('App\Comment');
}
public function commentsReceived()
{
return $this->hasMany('App\Comment', 'commentable_id', 'id');
}
public function hasRole(array $roles)
{
foreach ($roles as $role) {
if (isset(self::$roles[$role])) {
if (self::$roles[$role]) return true;
} else {
self::$roles[$role] = $this->roles()->where('name', $role)->exists();
if (self::$roles[$role]) return true;
}
}
return false;
}
public function scopeOfRoleType($query, $types)
{
return $query->whereHas('roles', function ($q) use ($types) {
$q->whereIn('name', $types);
});
}
public function userRatingCount()
{
return $this->hasMany('App\Comment', 'commentable_id', 'id')->where('enable', '=', '1')->where('to_stats', '=', '0');
}
}
$users= User::ofRoleType($role)
现在,我想显示带有摘要等级(comment.rating)的用户列表。
我有代码:
@foreach($users as $user)
- User: {{ $user->email }} has {{ ...votes (comment.rating).... }}
@endfor
我尝试了此代码,但这不起作用:
$users= User::ofRoleType($role)->with('userRatingCount')->sum('comments.rating')
我该如何修复?
您可以使用子查询来做到这一点。
首先,我们需要弄清楚查询的外观。
select `users`.*,
(
select sum(rating)
from `comments`
where `user_id` = `users`.`id`
) as `comments_rating`
from `users`
order by `comments_rating` desc
然后,我们只需要将该查询转换为Eloquent。
$commentsRating = Comment::selectRaw('sum(rating)')
->whereColumn('user_id', 'users.id')
->getQuery();
$users = User::select('users.*')
->selectSub($commentsRating, 'comments_rating')
->orderBy('comments_rating', 'DESC')
->get();
最后但并非最不重要的一点,我会告诉你很酷的事情。我们可以将该查询移至范围。因此,我们可以随时加载该查询。
class User extends Model
{
public function scopeWithCommentsRating($query)
{
$commentsRating = Comment::selectRaw('sum(rating)')
->whereColumn('user_id', 'users.id')
->getQuery();
$base = $query->getQuery();
if (is_null($base->columns)) {
$query->select([$base->from.'.*']);
}
return $query->selectSub($commentsRating, 'comments_rating');
}
}
然后,
$users = User::withCommentsRating()->orderBy('comments_rating', 'DESC')->get();
PS。我不知道userRatingCount
关系的目的是什么。
User::ofRoleType($role)->with('comments')->sortBy(function ($user) {
return $user->comments->sum('rating');
});