Как к отношениям моделей Eloquent добавить фильтры?
Есть SQL запрос вида
SELECT
count(command_id),
u.name AS uname,
c.name AS cmd
FROM logs l
JOIN users AS u ON u.uid = l.uid
JOIN commands AS c ON c.id = l.command_id
WHERE date(l.created_at) = '$date' AND u.name NOT IN ('".join("','",$exclude_users)."')")
GROUP BY u.name,c.name
Конструктором запросов оно воспроизводится легко:
public static function getDayLogs ($date, $exclude_users):Collection {
return DB::table(self::LOGS, 'l')
->select('u.name as uname', 'c.name as cmd')
->selectRaw('count(command_id)')
->join('users as u', 'u.uid', '=', 'l.uid')
->join('commands as c', 'c.id', '=', 'l.command_id')
->whereRaw("date(l.created_at) = '$date' AND u.name NOT IN ('".join("','", $exclude_users)."')")
->groupBy('u.name', 'c.name')
->get();
}
Вопрос: возможно ли это воспроизвести посредством моделей Eloquent?
use Illuminate\Database\Eloquent\Model;
/**
* @property int $id
* @property string $created_at
* @property int $uid
* @property int $command_id
* @property string $command_params
* @property string $response
*/
class Logs extends Model {
protected $table = 'logs';
public function user () {
return $this->belongsTo(Users::class, 'uid');
}
public function command () {
return $this->belongsTo(Commands::class, 'command_id');
}
use Illuminate\Database\Eloquent\Model;
/**
* @property int $id
* @property string $created_at
* @property int $uid
* @property string $time_start
* @property string $name
* @property string $territory
* @property bool $protected
*/
class Commands extends Model {
protected $table = 'commands';
public function logs () {
return $this->hasMany(Logs::class, 'id');
}
}
use Illuminate\Database\Eloquent\Model;
/**
* @property int $id
* @property string $created_at
* @property int $uid
* @property string $time_start
* @property string $name
* @property string $territory
* @property bool $protected
*/
class Users extends Model {
protected $table = 'users';
protected $primaryKey = 'uid';
public function logs () {
return $this->hasMany(Logs::class, 'uid');
}
}
Максимум, что у меня получилось - это получить объекты user и command для каждого объекта в наборе logs
Logs::with(['user','command'])->whereRaw("date(created_at) = '2025-03-01'")->get();
Illuminate\Database\Eloquent\Collection {#5731
all: [
Models\DB\Logs {#5438
id: 839165,
created_at: "2025-03-01 12:23:43",
uid: 12345,
command_id: 23,
command_params: "test, 19",
response: """
test\n
""",
user: Models\DB\Users {#5467
id: 642,
created_at: "2024-02-19 00:00:00",
uid: 12345,
name: "testUser",
territory: "27",
protected: false,
is_admin: false,
created_by: null,
},
command: Models\DB\Commands {#5879
id: 23,
name: "short",
name_rus: "short",
arguments: "["улица,дом"]",
description: "test description",
example: "short A,H",
skiplog: false,
showhelp: true,
},
},
...
]
}
а суть именно в group by и count(command_id). Есть идеи, как это можно сделать? И непонятно, как к отношению user приделать whereNotIn()...
Источник: Stack Overflow на русском