如何使用轴关系设置附加过滤器?

huangapple go评论45阅读模式
英文:

How with pivot relation set additive filter?

问题

在Laravel 9应用程序中,我使用多对多关系与名为article_vote的表连接了两个表:

return new class extends Migration {
    public function up()
    {
        Schema::create('article_vote', function (Blueprint $table) {
            $table->id();
            $table->foreignId('article_id')->references('id')->on('articles')->onUpdate('RESTRICT')->onDelete('CASCADE');
            $table->foreignId('vote_id')->references('id')->on('votes')->onUpdate('RESTRICT')->onDelete('CASCADE');
            
            // ...
        });
    }
}

在app/Models/Article.php模型中,我有以下关系:

public function onlyActiveVotes(): BelongsToMany
{
    return $this->belongsToMany(Vote::class, 'article_vote', 'article_id')
        ->withTimestamps()
        ->wherePivot('active', true)
        ->withPivot(['active', 'expired_at', 'supervisor_id', 'supervisor_notes']);
}

我想通过文章ID($id)获取文章:

$article = Article::getById($id)
    ->firstOrFail();

使用onlyActiveVotes关系从投票中获取过滤数据:

$voteTableName = ((new Vote)->getTable());
$articleVotes = $article->onlyActiveVotes()->whereHas('votes', function ($query) use($request, $voteTableName)   {
    $query->where($voteTableName . '.vote_category_id', $request->filter_vote_vote_category_id);
})->get();

但是它不起作用,我收到错误消息:

Method Illuminate\Database\Eloquent\Relations\BelongsToMany::whereHas does not exist.

下面的代码返回一个集合:

dd($article->onlyActiveVotes);

下面的代码返回BelongsToMany:

dd($article->onlyActiveVotes());

在以下代码中:

dd($article->onlyActiveVotes()->query);

我得到错误:

Cannot access protected property Illuminate\Database\Eloquent\Relations\BelongsToMany::$query

是否有一种方法可以在onlyActiveVotes关系上使用whereHas?

英文:

In laravel 9 app I use many to many relation with table article_vote joining 2 tables :

return new class extends Migration {
    public function up()
    {
        Schema::create('article_vote', function (Blueprint $table) {
            $table->id();
            $table->foreignId('article_id')->references('id')->on('articles')->onUpdate('RESTRICT')->onDelete('CASCADE');
            $table->foreignId('vote_id')->references('id')->on('votes')->onUpdate('RESTRICT')->onDelete('CASCADE');

            ...
            
        });

    }

In app/Models/Article.php model I have relation :

public function onlyActiveVotes(): BelongsToMany
{
    return $this->belongsToMany(Vote::class, 'article_vote', 'article_id')
        ->withTimestamps()
        ->wherePivot('active', true)
        ->withPivot(['active', 'expired_at', 'supervisor_id', 'supervisor_notes']);
}

and I want having Article by Id($id)

$article      = Article::getById($id)
    ->firstOrFail();

Using onlyActiveVotes relation to get filtered data from vote :

$voteTableName = ((new Vote)->getTable());
$articleVotes = $article->onlyActiveVotes()::whereHas('votes', function ($query) use($request, $voteTableName)   {
    $query->where($voteTableName . '.vote_category_id', $request->filter_vote_vote_category_id);
})->get();

It does not work, as I got error :

Method Illuminate\Database\Eloquent\Relations\BelongsToMany::whereHas does not exist. i

Line below returns collection

dd($article->onlyActiveVotes );

Line below returns BelongsToMany:

dd($article->onlyActiveVotes() );


Illuminate\Database\Eloquent\Relations\BelongsToMany {#2283 // app/Repositories/ArticleToManyVotesRepository.php:74
  #query: Illuminate\Database\Eloquent\Builder {#2218
    #query: Illuminate\Database\Query\Builder {#2268

On

dd($article->onlyActiveVotes()->query );

I got error:

Cannot access protected property Illuminate\Database\Eloquent\Relations\BelongsToMany::$query

If there is a way to use whereHas with onlyActiveVotes relation ?

Updated BLOCK :

I hope I clearly exoplaned what I want : want to get only filtered votes which arerelated with pivot through $article model

Aftet I fixed :

$filteredArticleVotes = $article->onlyActiveVotes()->whereHas

I got other error :

Call to undefined method App\Models\Vote::onlyActiveVotes() 

pointing at line

$filteredArticleVotes = $article->onlyActiveVotes()->whereHas('onlyActiveVotes', function ($query) use($request, $voteTableName)   {
    $query->where($voteTableName . '.vote_category_id', $request->filter_vote_vote_category_id);
})->get();

As I wrote in my post Article model has onlyActiveVotes method and I expected the code above have to work, but it did not...

Thanks!

答案1

得分: 1

由于 onlyActiveVotes() 已经返回了一个用于投票表的查询构建器,您可以直接链式调用 where() 方法来按照 vote_category_id 列来筛选结果。在这种情况下,whereHas() 方法是不必要的。

$articleVotes = $article->onlyActiveVotes()
    ->where('vote_category_id', $request->filter_vote_vote_category_id)
    ->get();
英文:

Since onlyActiveVotes() already returns a query builder for the votes table, you can directly chain the where() method to filter the results by the vote_category_id column. The whereHas() method is not necessary in this case.

$articleVotes = $article->onlyActiveVotes()
    ->where('vote_category_id', $request->filter_vote_vote_category_id)
    ->get();

huangapple
  • 本文由 发表于 2023年2月18日 15:01:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/75491730.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定