简体   繁体   English

Laravel过滤有很多结果

[英]Laravel filtering hasMany results

I have three tables - Campaigns, Actions and Activists. 我有三个表 - 活动,行动和活动家。 A Campaign has many Actions, and an Action belongs to both an Activist and a Campaign. Campaign有许多操作,Action属于Activist和Campaign。

Each action has a client_id (from the client_id of the campaign it belongs to), so when a client views a list of activists, they should only see those who have taken an action on one of their campaigns. 每个操作都有一个client_id(来自其所属广告系列的client_id),因此当客户查看活动家列表时,他们应该只看到那些对其中一个广告系列采取了操作的人。

Likewise, when viewing an individual activist, they should only see those actions related to their campaigns. 同样,在查看个人活动家时,他们应该只看到与其广告系列相关的操作。

Models 楷模

Campaign.php Campaign.php

public function actions()
{
    return $this->hasMany('Action');
}

Action.php action.php的

public function campaign()
{
    return $this->belongsTo('Campaign', 'campaign_id');
}

public function activist()
{
    return $this->belongsTo('Activist', 'activist_id');
}

Activists.php Activists.php

public function actions()
{
    return $this->hasMany('Action');
}

Controllers 控制器

ActivistsController.php ActivistsController.php

public function index()
{
    $activists = Activist::with('actions')->whereHas('actions', function($q) {
        $user = Sentry::getUser();
        $q->where('client_id', $user->client_id);
    }))->get();

    foreach ($activists as $activist)
    {
         $activist->total = $activist->actions()->count();
    }
}

public function getActivist($id)
{
    $activist = Activist::with('actions')->whereHas('actions', function($q) {
        $user = Sentry::getUser();
        $q->where('client_id', $user->client_id);
    })->find($id);

    $activist->total = $activist->actions()->count();
}

I'm seeing the following: 我看到以下内容:

On the /activists page, I'm correctly seeing only those activists who have taken an action related to my client_id, but also every action they've taken. 在/ activists页面上,我正确地看到那些采取了与我的client_id相关的操作的活动家,以及他们采取的每一个行动。 Likewise, count() returns a full count of all the activists' actions. 同样,count()返回所有活动家的动作的完整计数。

On the /activists/{id} page, it correctly returns null if the activist hasn't taken any actions related to my client_id, but where they have, I again see all of their actions and a full count. 在/ activists / {id}页面上,如果激活者没有采取任何与我的client_id相关的操作,它会正确地返回null,但是在他们拥有的地方,我再次看到他们的所有操作和完整计数。

AFL. AFL。 There's something blinding obvious I'm missing, right? 有一些明显让我失踪的东西,对吧?

Thanks. 谢谢。

[edit] Updated to add: [edit]更新以添加:

Using the client_id filter on both with and whereHas rectifies the 'all actions appearing regardless' issue, but the count issue remains (and I'm not sure this is remotely the right way to improve this): 在with和whereHas上使用client_id过滤器可以纠正“无论出现的所有操作”问题,但计数问题仍然存在(我不确定这是远程正确的改进方法):

ActivistController.php ActivistController.php

public function index()
{
    $filter = function($q) {
        $user = Sentry::getUser();
        $q->where('client_id', $user->client_id);
    };

    $activists = Activist::with(array('actions' => $filter))
    ->whereHas('actions', $filter)
    ->get();
}

public function getActivist($id)
{
    $filter = function($q) {
            $user = Sentry::getUser();
            $q->where('client_id', $user->client_id);
    };

    $activist = Activist::with(array('actions' => $filter))
    ->whereHas('actions', $filter)
    ->find($id);
}

I've solved this now, but for reference: 我现在已经解决了这个问题,但供参考:

$activist->actions()->count()

This, obviously in hindsight, ignores any of the prior queries and simply counts data returned from the actions() method as defined in the activist model. 事实上,这很明显地忽略了任何先前的查询,并简单地计算从激活模型中定义的actions()方法返回的数据。

I should have provided an alternate method in the model that includes the appropriate where function, like so: 我应该在模型中提供一个替代方法,包括适当的where函数,如下所示:

public function actionsClient($id)
{
    return $this->hasMany('Action')->where('client_id', $id);
}

Meaning the count could then be invoked with: 这意味着可以使用以下命令调用计数:

$activist->total = $activist->actionsClient($id)->count();

for a single campaign and 对于单个广告系列和

foreach ($activists as $activist)
{
    $activist->total = $activist->actionsClient($activist->id)->count();
}

on the index. 在索引上。 I'd previously tried this, but as described here - How to access model hasMany Relation with where condition? 我之前尝试过这个,但是如此处所述 - 如何访问模型hasMany Relation with where condition? - relations must be described in camelCase (actions_client > actionsClient). - 必须在camelCase中描述关系(actions_client> actionsClient)。

In my usage this worked for me: 在我的用法中,这对我有用:

$clients = Profile::select('id', 'name')->orderBy('initial')->whereHas('type', function ($query) {
    $query->where('slug', 'client');
})->office()->pluck('name', 'id');

你已经有$ activist的实例急切加载他们的行为,这意味着你已经知道活动家的行为因为他们已经在实例中了,所以为什么再次调用actions()而不是这样做:

$activist->actions->count()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM