Laravel filtering has many results

I have three tables - Campaigns, Actions, and Activists. A campaign has many actions and the action belongs to both the activist and the campaign.

Every action has a client_id (from the client_id of the campaign to which it belongs), so when a client views the list of activists, they should only see those who took action in one of their campaigns.

Likewise, when viewing an individual activist, they should only see activities related to their campaigns.

Models

Campaign.php

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

      

action.php

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

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

      

Activists.php

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

      

Controllers

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 see the following:

On the / activists page, I correctly see only those activists who took the action associated with my client_id, but also every action they took. Likewise, count () returns the total count of all activists' actions.

On the page / activists / {id}, it correctly returns null if the activist has not taken any action related to my client_id, but where they are I can see all their actions and the full score again.

AFL. There is something blindingly obvious, I am missing, right?

Thank.

[edit] Updated to add:

Using the client_id filter with both whereHas and whereHas fixes the "all actions occurring independently" problem, but the counting problem remains (and I'm not sure if this is the remote correct way to improve this):

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);
}

      

+3


source to share


2 answers


I solved it now, but for reference:

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

      

This, obviously in retrospect, ignores any of the previous requests and simply counts the data returned by the actions () method as defined in the activist model.

I had to provide an alternative method in the model that includes the corresponding function, for example:

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

      



The count value can be called with:

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

      

for one campaign and

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

      

by index. I've tried this before, but as described here, How to access the hasMany Relation model, where is the condition? - relationships must be described in camelCase (actions_client> actionsClient).

+4


source


In my use, this worked for me:



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

      

0


source







All Articles