在 laravel json 关系预加载响应中类型转换
type casting in laravel json response in relationships eager loading
这是我的 post 模型。
class Post extends Model
{
use SoftDeletes;
protected $table = 'posts';
protected $fillable = ['title','featuring_image', 'brief', 'body', 'seen_count'];
public function user(){
return $this->belongsTo(User::class);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
public function someComments()
{
return $this->comments()->limit(Constants::COMMENTS_COUNT_LIMIT);
}
public function commentsCount()
{
return $this->comments()
->selectRaw('post_id, count(*) as count')
->groupBy('post_id');
}
public function likes()
{
return $this->hasMany(Like::class);
}
public function isLiked()
{
return $this->likes()->where('user_id', auth()->check() ? auth()->user()->id : 0);
}
public function likesCount()
{
return $this->likes()
->selectRaw('post_id, count(*) as count')
->groupBy('post_id');
}
}
我在这个模型上执行了这个查询。
$post = Post::with(['categories', 'user', 'commentsCount', 'likesCount', 'isLiked'])->find($post->id);
因为这个table和点赞和评论table之间的关系,'commentsCount', 'likesCount', 'isLiked'
这个查询的输出是一个数组。但是我需要在 laravel josn 响应中接收 'commentsCount'
和 'likesCount'
的数字,以及 'isliked'
的布尔值作为输出。
您可能会发现使用 Eloquent 附带的 withCount() 更容易。
然后对于 is_liked
,您可以使用范围来获取值并将 cast
其转换为布尔值:
public function scopeIsLiked($query)
{
if (is_null($query->getQuery()->columns)) {
$query->select([$query->getQuery()->from . '.*']);
}
$relation = Relation::noConstraints(function () {
return $this->likes();
});
$q = $this->likes()->getRelationExistenceCountQuery(
$relation->getRelated()->where('user_id', auth()->check() ? auth()->user()->id : 0)->newQuery(), $query
);
$query->selectSub($q->toBase(), 'is_liked');
}
请注意,您需要将 Relation
的 use
语句添加到 class:
的顶部
use Illuminate\Database\Eloquent\Relations\Relation;
您的模型可能看起来像:
class Post extends Model
{
use SoftDeletes;
protected $table = 'posts';
protected $fillable = ['title', 'featuring_image', 'brief', 'body', 'seen_count'];
public function user()
{
return $this->belongsTo(User::class);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
public function someComments()
{
return $this->comments()->limit(Constants::COMMENTS_COUNT_LIMIT);
}
public function likes()
{
return $this->hasMany(Like::class);
}
/**
* Scope to add the "is_liked" flag.
*
* @param $query
*/
public function scopeIsLiked($query)
{
if (is_null($query->getQuery()->columns)) {
$query->select([$query->getQuery()->from . '.*']);
}
$relation = Relation::noConstraints(function () {
return $this->likes();
});
$q = $this->likes()->getRelationExistenceCountQuery(
$relation->getRelated()->where('user_id', auth()->check() ? auth()->user()->id : 0)->newQuery(), $query
);
$query->selectSub($q->toBase(), 'is_liked');
}
}
您的查询将类似于:
$post = Post::with('categories', 'user')
->withCount('likes', 'comments')
->isLiked()
->find($post->id);
希望对您有所帮助!
您可以使用 Laravel 转换:
在每个模型中,您可以添加以下内容来转换一个值,例如:
protected $casts = [
'isLiked' => 'boolean',
];
gives a nice solution using scopes, but for laravel 5.4+ you could get away with aliasing the withCount()
result and then casting it to boolean with a $cast
variable on the model or an accessor(使用访问器,您只能获得蛇形盒is_liked
)。这样我们就不需要写复杂的作用域了。
模型将是
class Post extends Model
{
// rest of model
protected $casts = ['isLiked'=>'boolean'];
public function likes()
{
return $this->hasMany(Like::class);
}
}
然后在你的控制器中
$post = Post::with('categories', 'user')
->withCount(
[
'likes as likesCount', 'comments as commentsCount',
'likes as isLiked' =>function($query){
$query->where('user_id', auth()->check() ? auth()->user()->id : 0);
}
]
)
->find($post->id);
现在你得到 likesCount
(int), commentsCount
(int) and isLiked
(boolean)
这是我的 post 模型。
class Post extends Model
{
use SoftDeletes;
protected $table = 'posts';
protected $fillable = ['title','featuring_image', 'brief', 'body', 'seen_count'];
public function user(){
return $this->belongsTo(User::class);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
public function someComments()
{
return $this->comments()->limit(Constants::COMMENTS_COUNT_LIMIT);
}
public function commentsCount()
{
return $this->comments()
->selectRaw('post_id, count(*) as count')
->groupBy('post_id');
}
public function likes()
{
return $this->hasMany(Like::class);
}
public function isLiked()
{
return $this->likes()->where('user_id', auth()->check() ? auth()->user()->id : 0);
}
public function likesCount()
{
return $this->likes()
->selectRaw('post_id, count(*) as count')
->groupBy('post_id');
}
}
我在这个模型上执行了这个查询。
$post = Post::with(['categories', 'user', 'commentsCount', 'likesCount', 'isLiked'])->find($post->id);
因为这个table和点赞和评论table之间的关系,'commentsCount', 'likesCount', 'isLiked'
这个查询的输出是一个数组。但是我需要在 laravel josn 响应中接收 'commentsCount'
和 'likesCount'
的数字,以及 'isliked'
的布尔值作为输出。
您可能会发现使用 Eloquent 附带的 withCount() 更容易。
然后对于 is_liked
,您可以使用范围来获取值并将 cast
其转换为布尔值:
public function scopeIsLiked($query)
{
if (is_null($query->getQuery()->columns)) {
$query->select([$query->getQuery()->from . '.*']);
}
$relation = Relation::noConstraints(function () {
return $this->likes();
});
$q = $this->likes()->getRelationExistenceCountQuery(
$relation->getRelated()->where('user_id', auth()->check() ? auth()->user()->id : 0)->newQuery(), $query
);
$query->selectSub($q->toBase(), 'is_liked');
}
请注意,您需要将 Relation
的 use
语句添加到 class:
use Illuminate\Database\Eloquent\Relations\Relation;
您的模型可能看起来像:
class Post extends Model
{
use SoftDeletes;
protected $table = 'posts';
protected $fillable = ['title', 'featuring_image', 'brief', 'body', 'seen_count'];
public function user()
{
return $this->belongsTo(User::class);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
public function someComments()
{
return $this->comments()->limit(Constants::COMMENTS_COUNT_LIMIT);
}
public function likes()
{
return $this->hasMany(Like::class);
}
/**
* Scope to add the "is_liked" flag.
*
* @param $query
*/
public function scopeIsLiked($query)
{
if (is_null($query->getQuery()->columns)) {
$query->select([$query->getQuery()->from . '.*']);
}
$relation = Relation::noConstraints(function () {
return $this->likes();
});
$q = $this->likes()->getRelationExistenceCountQuery(
$relation->getRelated()->where('user_id', auth()->check() ? auth()->user()->id : 0)->newQuery(), $query
);
$query->selectSub($q->toBase(), 'is_liked');
}
}
您的查询将类似于:
$post = Post::with('categories', 'user')
->withCount('likes', 'comments')
->isLiked()
->find($post->id);
希望对您有所帮助!
您可以使用 Laravel 转换: 在每个模型中,您可以添加以下内容来转换一个值,例如:
protected $casts = [
'isLiked' => 'boolean',
];
withCount()
result and then casting it to boolean with a $cast
variable on the model or an accessor(使用访问器,您只能获得蛇形盒is_liked
)。这样我们就不需要写复杂的作用域了。
模型将是
class Post extends Model
{
// rest of model
protected $casts = ['isLiked'=>'boolean'];
public function likes()
{
return $this->hasMany(Like::class);
}
}
然后在你的控制器中
$post = Post::with('categories', 'user')
->withCount(
[
'likes as likesCount', 'comments as commentsCount',
'likes as isLiked' =>function($query){
$query->where('user_id', auth()->check() ? auth()->user()->id : 0);
}
]
)
->find($post->id);
现在你得到 likesCount
(int), commentsCount
(int) and isLiked
(boolean)