Как проверить, есть ли в таблице условие where в Laravel Query Builder? - PullRequest
1 голос
/ 11 февраля 2020

Здесь - пример того, как мы можем определить, была ли таблица уже включена в запрос в Laravel или нет.

public static function isJoined($query, $table)
    {
        $joins = $query->getQuery()->joins;
        if($joins == null) {
            return false;
        }

        foreach ($joins as $join) {
            if ($join->table == $table) {
                return true;
            }
        }

        return false;
    }

Мне нужно извлечь предложения where в запросе.

У меня есть запрос с условиями join и некоторыми условиями where, мне нужно используйте одно из этих where условий для вложенного выбора.

Теперь мне нужно извлечь предложение where из запроса и использовать его еще раз. Вопрос в том, как определить, содержит ли мой запрос какое-либо условие where в указанном c столбце таблицы (например, org.id) в моем запросе Eloquent или нет?

Я пытался извлечь wheres из запроса следующим образом, но он не похож на то, что мы имеем для объединений

$wheres = $query->getQuery()->wheres;
  foreach ($wheres as $where) {
    dd(array_keys($where));
  }

И то, что я получил:

array:3 [
  0 => "type"
  1 => "query"
  2 => "boolean"
]

Значение type равно nested и если я попробую следующий код:

$wheres = $query->getQuery()->wheres;
  foreach ($wheres as $where) {
     dd($where['query']->wheres);
  }

Тогда у меня будет:

array:1 [
  0 => array:5 [
    "type" => "Basic"
    "column" => "org.path"
    "operator" => "LIKE"
    "value" => "/202001/10000000/12400000%"
    "boolean" => "and"
  ]
]

Теперь, почему первый wheres возвращает другой объект? Я ожидал такого результата в первом $where!

Ответы [ 2 ]

2 голосов
/ 11 февраля 2020

Вы можете сделать то же самое со свойством ->wheres построителя запросов. Он будет содержать массив предложений where в следующем формате:

    ["type"] => string(5) "Basic"
    ["column"] =>string(1) "q"
    ["operator"] => string(1) "="
    ["value"] => int(2)
    ["boolean"] => string(3) "and"

Исходя из этого, вы можете использовать свойство column .

UPD: По сути, вы можете создать рекурсивную функцию, которая будет проверять ее для вас:

  ...
  $wheres = $query->getQuery()->wheres;
  foreach ($wheres as $where) {
     if( $checkColumn($where, 'myColumn) ) { 
        // found it
        break;
     }
  }

  function checkColumn($where, $column) {
     if( $where['type'] == 'nested' ) {
         return checkColumn($where['query'], $column);
     }
     else {
        return $where['column'] == $column;
    }
  }
0 голосов
/ 11 февраля 2020

Вот моя рекурсивная функция, которую можно поместить в класс Model:

    /**
     * Returns the where conditions on a specific joined table?
     * @return array of wheres 
     */
    protected function wheres($query, $table){ 
        $conditions = [];
        if($query instanceof \Illuminate\Database\Eloquent\Builder){
            $wheres = $query->getQuery()->wheres;
        } elseif($query instanceof \Illuminate\Database\Query\Builder) {
            $wheres = $query->wheres;
        }

        if($wheres == null) {
            return [];
        }

        foreach ($wheres as $where) {
            if (isset($where['column']) && substr_compare($where['column'], $table, 0, strlen($table)) === 0){
                array_push($conditions, $where);
            } else if (isset($where['query'])){
                $conditions = array_merge($conditions, $this->wheres($where['query'], $table));
            }
        }
        return $conditions;
    }

Она может быть вызвана в контроллерах следующим образом:

$wheres = $this->wheres($query, 'org');
foreach($wheres as $where){
   ....
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...