Как к отношениям моделей Eloquent добавить фильтры?

Рейтинг: 0Ответов: 0Опубликовано: 04.03.2025

Есть 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()...

Ответы

Ответов пока нет.