Как сравнить связанный счетчик с собственным столбцом в Laravel Eloquent? - PullRequest
0 голосов
/ 14 апреля 2019

Предположим, у нас есть таблица agents со столбцом quota и отношением "многие ко многим" к tickets. С Laravel Eloquent ORM, как я могу выбрать только агентов, у которых количество билетов меньше или равно их количеству, чем их квота?

Следует избегать загруженных объектов.

class Agent extends Model {

   public function tickets()
   {
      return $this->belongsToMany(Ticket::class, 'agent_tickets')->using(AgentTicket::class);
   }

   public function scopeQuotaReached($query)
   {
      // Does not work. withCount is an aggregate.
      return $query->withCount('tickets')->where('tickets_count', '<=', 'quota');

      // Does not work. Tries to compare against the string "quota".
      return $query->has('tickets', '<=', 'quota');
   }

}

Есть ли более красноречивый (каламбур) способ решить эту проблему, чем использование запроса DB::raw() с объединением, группировкой и подсчетом вручную?

EDIT

Работает:
$query->withCount('tickets')->having('tickets_count', '<=', DB::raw('quota'))->get();

Работает:
$query->withCount('tickets')->having('tickets_count', '<=', DB::raw('quota'))->exists();

Перерывы: (бросает)
$query->withCount('tickets')->having('tickets_count', '<=', DB::raw('quota'))->count();

СВЯЗАННЫХ

https://github.com/laravel/framework/issues/14492
Вопрос закрыт, ссылки на # 9307 я выложил там. Будем следить.

Ответы [ 2 ]

2 голосов
/ 14 апреля 2019

Производные столбцы, такие как tickets_count, доступны только в предложении HAVING.

Поскольку нет метода havingColumn(), вам придется использовать необработанное выражение:

$query->withCount('tickets')->having('tickets_count', '<=', DB::raw('quota'));
0 голосов
/ 14 апреля 2019

На уровне базы данных я не знаю, как этого добиться, но вы могли бы сделать это на уровне Коллекции.

// Get users
$agents = Agent::withCount('tickets')->get();
// filter
$good_agents = $agents->filter(function ($agent, $key) {
                   return $agent->tickets_count >= $agent->quota;
               })
               ->all();

Конечно, вы можете встроить это:

$good_agents = Agent
    ::withCount('tickets')
    ->get()
    ->filter(function ($agent, $key) {
        return $agent->tickets_count >= $agent->quota;
    })
    ->all();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...