Я пытаюсь убедиться, что запись существует в базе данных, прежде чем выполнять действие, связанное с пользователем. Когда я выполняю запрос непосредственно в моем PHPMyAdmin (для целей тестирования).
SELECT * FROM `chat_participants` WHERE `chat_id` = 2 AND `user_id` = 2
Я получаю правильную запись. Однако, когда я пытаюсь использовать Laravel Query Builder для достижения того же.
dd($this->participants
->where('chat_id', '=', 2)
->where('user_id', '=', 2)
->get()
->first());
Я получаю null.. Есть ли способ убедиться, что запись существует в базе данных с помощью Query Builder? Нужно ли объявлять AND в построителе запросов?
Обновление: я установил переменную participants в своем конструкторе.
public function __construct()
{
$this->middleware('auth');
$this->header = DB::table('chat_headers');
$this->participants = DB::table('chat_participants');
$this->messages = DB::table('chat_messages');
}
toSql() производит:
select * from chat_participants`
inner join chat_headers on chat_headers.id = chat_participants.chat_id
inner join chat_rbac on chat_rbac.id = chat_participants.rbac
where chat_participants.chat_id = ? and chat_participants.user_id = ?
and chat_id = ? and user_id = ?
Обновлен вопрос, чтобы показать @Devon
Сделайте $this->participants->where('chat_id', '=', 2)->where('user_id', '=', 2)->toSql(), чтобы увидеть, какой SQL-запрос генерируется. Несколько вызовов where() автоматически объединяются в AND. Примечание: ->get()->first() может быть просто ->first().
->get()->first() кстати избыточен; ->get() вернет Collection записей, соответствующих вашему запросу, после чего ->first() вернет первую из этих записей. Вы можете просто использовать ->first(), чтобы сэкономить время вычислений.
Внутреннее соединение "select * from chat_participants` chat_headers на chat_headers.id = chat_participants.chat_id внутреннее соединение chat_rbac на chat_rbac.id = chat_participants.rbac, где chat_participants.chat_id = ? и chat_participants.user_id = ? и chat_id = ? и user_id = ?` @ceejayoz
@Jaquarh А? Это совсем другой запрос. Ни один из кодов, которые вы показываете, не выполняет JOIN.
Я знаю, меня это тоже смутило! Я использую $this->participants несколько раз, так что, возможно, он помнит свое предыдущее состояние... Возможно, мне нужно использовать DB::table('chat_participants'), а не $this->participants? @ceejayoz
@Jaquarh, вы должны манипулировать свойством участников в другом месте, прежде чем дойдете до этой строки, иначе у вас здесь неправильная строка.
Да, кажется, что когда я раньше использовал $this->participants, он запоминал все соединения, которые я использовал. Возможно, мне нужно снова использовать DB::table()? @Девон
Возможно, я не знаю вашего проекта или почему вы снова и снова используете один и тот же объект запроса, но да, объекты всегда передаются в качестве ссылки в PHP, поэтому, конечно, он запомнит состояние.
@Jaquarh Да, если в другом коде используется одна и та же переменная $this->participants, их различные соединения, где и еще много чего все еще будут там. Начните с нового построителя запросов.
Я всегда думал, что вам нужно использовать &= для передачи по ссылке? Не стесняйтесь делать это ответом с этим объяснением @Devon, и я соглашусь. Спасибо за помощь обоим! @ceejayoz






В PHP объекты передаются по ссылке, это означает, что вы передаете указатель на один и тот же объект Query Builder везде, где используете свойство participants. Таким образом, в большинстве случаев вы захотите создать новый объект построителя запросов для каждого запроса.
Однако PHP позволяет клонировать объекты, что позволит вам передать базовый построитель запросов и начать новый повсюду, который вы используете:
$query = clone $this->participants;
$query->where(..)->first();
Это реализация шаблона Prototype OO, создайте базовый объект, а затем создайте его копию, чтобы выполнить специфику.
Это был бы только один из способов избежать жесткого кодирования имени вашей таблицы везде, где вы ее запрашиваете.
Спасибо вам за эту информацию! Вы реализовали концепцию создания собственности участников, чтобы сохранить постоянное написание DB::table(). Я понятия не имел, что вы можете использовать ключевое слово clone вот так!
Какое здесь свойство
participants?