从与主模型列的关系中获取列的更好解决方案

问题描述

需要更好的解决方

一个 Post 属于多个 Categories 并且它们之间具有多对多关系。多对多关系的中间表是PostCategoryPostCategory 包含帖子的 post_idcategory_idsequence。我想通过 sequence 模型属性标题、描述等)获取Post

为了得到这个,我这样做

$posts = Post::where([
    'is_active' => 1,'is_deleted' => 0,'is_published' => 1,'status' => 'publish'
])->whereHas('category',function ($query) use ($params) {
    return $query->where([
        'category_id' => $params['categoryId'],]);
})->with([
    'category' => function ($query) use ($params) {
        return $query->where([
            'category_id' => $params['categoryId'],]);
    }
])
    ->orderBy('live_date','DESC')
    ->orderBy('publish_time','DESC')
    ->get()
    ->toArray();
    
foreach ($posts as &$post) {
    $post['sequence'] = $post['category']['sequence'];
}

我得到了预期的结果,但正如你所看到的,首先我必须使用闭包两次,然后必须遍历整个集合以在顶层设置 sequence 但正如我提到的,我需要一个更好的解决方案(如果有的话)

Post.PHP

namespace App\Models\Mongo;


/**
 * @mixin \Illuminate\Database\Eloquent\Builder
 * @mixin \Jenssegers\Mongodb\Query\Builder
 */
class POST extends \Jenssegers\Mongodb\Eloquent\Model
{
    /** @var string Mongo Connection Name */
    //protected $connection = 'mongodb';

    /** @var string Mongo Collection Name */
    protected $collection = 'posts';

    /** @var bool Enable/disable Timestamp */
    public $timestamps = true;

    /** @var string Date format */
    protected $dateFormat = 'Y-m-d H:i:s';

    /** @var array */
    protected $dates = ['created_at','updated_at','live_date','expire_date'];

    /**
     * // I kNow this relation is not correct,it must either belongsToMany or hasMany
     * // but as of Now,I've to fetch the posts belonging to a single category id
     * // so using hasOne relation
     * @return \Jenssegers\Mongodb\Relations\HasOne
     */
    public function category()
    {
        return $this->hasOne(
            PostCategory::class,'post_id','_id'
        );
    }
}

PostCategory.PHP

namespace App\Models\Mongo;


/**
 * @mixin \Illuminate\Database\Eloquent\Builder
 * @mixin \Jenssegers\Mongodb\Query\Builder
 */
class PostCategory extends \Jenssegers\Mongodb\Eloquent\Model
{
    /** @var string Mongo Connection Name */
    //protected $connection = 'mongodb';

    /** @var string Mongo Collection Name */
    protected $collection = 'post_category';

    /**
     * @return \Jenssegers\Mongodb\Relations\HasMany
     */
    public function post()
    {
        return $this->hasMany(Post::class,'_id','post_id');
    }
}

变化

更改与 belongsToMany 中的 Post 的关系

关系不起作用

return $this->belongsToMany(
    Category::class,'post_category','category_id',<-- post primary key
    '_id',<-- category primary key
)->withPivot('sequence');

解决方法

您可以改用 many-to-many relationship 并以 pivot column 的身份访问 sequence

namespace App\Models\Mongo;


/**
 * @mixin \Illuminate\Database\Eloquent\Builder
 * @mixin \Jenssegers\Mongodb\Query\Builder
 */
class POST extends \Jenssegers\Mongodb\Eloquent\Model
{
    /** @var string Mongo Connection Name */
    //protected $connection = 'mongodb';

    /** @var string Mongo Collection Name */
    protected $collection = 'posts';

    /** @var bool Enable/Disable Timestamp */
    public $timestamps = true;

    /** @var string Date format */
    protected $dateFormat = 'Y-m-d H:i:s';

    /** @var array */
    protected $dates = ['created_at','updated_at','live_date','expire_date'];

    /**
     * // I know this relation is not correct,it must either belongsToMany or hasMany
     * // but as of now,I've to fetch the posts belonging to a single category id
     * // so using hasOne relation
     * @return \Jenssegers\Mongodb\Relations\HasOne
     */
    public function category()
    {
        return $this->belongsToMany(
            Category::class
        )->withPivot('sequence');
    }
}

您可能需要向 belongsToMany() 添加一个或多个可选参数才能使其工作。但既然你比我更了解你的数据结构,我敢打赌,你能比我更快地弄清楚这一点。