Как упростить этот код Laravel PHP до одного запроса Eloquent?
Я предполагаю, что все это должно быть в одном запросе, чтобы предотвратить дублирование данных в базе данных. Правильно ли это?
Как упростить этот код в один запрос Eloquent?
$user = User::where( 'id', '=', $otherID )->first();
if( $user != null )
{
if( $user->requestReceived() )
accept_friend( $otherID );
else if( !$user->requestSent() )
{
$friend = new Friend;
$friend->user_1= $myID;
$friend->user_2 = $otherID;
$friend->accepted = 0;
$friend->save();
}
}
Ответы
Ответ 1
Я бы сказал, что если есть связь между User
и Friend
, вы можете просто использовать модельные отношения Laravel, например:
$status = User::find($id)->friends()->updateOrCreate(['user_id' => $id], $attributes_to_update));
Это то, что я сделал бы, чтобы обновить новые данные или создать новый.
PS: Я использовал updateOrCreate() только для Laravel 5.2. *. И также было бы неплохо на самом деле сделать некоторую проверку на существование пользователя перед обновлением, но некоторые ошибки могут быть выброшены за нуль.
UPDATE
Я не уверен, что делать. Не могли бы вы объяснить немного больше, что я должен был сделать? Как насчет $attributes_to_update?
Хорошо. В зависимости от того, какие поля в таблице друзей отмечают двух друзей, теперь используйте ваш пример user_1
и user_2
. На примере, который я дал, $attributes_to_update
будет (если otherID
- новый идентификатор друга):
$attributes_to_update = ['user_2' => otherID, 'accepted' => 0 ];
Если ваша связь между User
и Friend
установлена правильно, то user_1
уже будет включен в вставку.
Кроме того, в этой функции updateOrCreate:
updateOrCreate($attributes_to_check, $attributes_to_update);
$attributes_to_check
будет означать те поля, которые вы хотите проверить, если они уже существуют, прежде чем создавать/обновлять новые, поэтому, если я хочу убедиться, проверка выполняется, когда accepted
есть 0
, тогда я могу передать оба слова `['user_1' = > 1, 'accepted' = > 0]
Надеюсь, теперь это ясно.
Ответ 2
Я предполагаю, что все это должно быть в одном запросе, чтобы предотвратить дублировать данные в базе данных. Правильно ли это?
Это не правильно. Вы предотвращаете дублирование, помещая ограничения unique
на уровень базы данных.
В буквальном смысле ничего вы можете делать на php или любом другом языке, в этом случае, чтобы предотвратить дубликаты, , если у вас нет уникальных ключей в вашей таблице ( с). Это простой факт, и если кто-нибудь скажет вам что-то другое - этот человек вопиюще ошибается. Я могу объяснить, почему, но объяснение будет длинным, поэтому я пропущу его.
Ваш код должен быть довольно простым - просто вставьте данные. Поскольку неясно, как обрабатывается уникальность (это выглядит как user_2, accepted
, но есть крайний случай), без какой-либо дополнительной формы данных вы - невозможно предложить полное решение.
Вы всегда можете игнорировать то, что я написал, и попытаться пойти с предлагаемыми решениями, но они потерпят неудачу, и вы получите дубликаты.
Ответ 3
Я предполагаю, что "друзья" здесь представляют собой отношение "многие ко многим" между пользователями. По-видимому, друг просит от одного пользователя (myID
) к другому (otherId
).
Вы можете представить это с помощью Eloquent как:
class User extends Model
{
//...
public function friends()
{
return $this->belongsToMany(User::class, 'friends', 'myId', 'otherId')->withPivot('accepted');
}
}
То есть, нет необходимости в модели Friend
.
Затем я думаю, что это эквивалентно тому, что вы хотите выполнить (если нет, пожалуйста, обновите с разъяснением):
$me = User::find($myId);
$me->friends()->syncWithoutDetaching([$otherId => ['accepted' => 0]]);
(accepted
0 или 1, согласно вашей бизнес-логике).
Этот метод sync
предотвращает дублирование вставок и обновляет или создает любую строку для данной пары "myId - otherId". Вы можете установить любое количество дополнительных полей в сводной таблице с помощью этого метода.
Однако я согласен с @Mjh об установке уникальных ограничений на уровне базы данных.
Ответ 4
Для такого рода проблем, прежде всего, вам нужно пользоваться кодом и базой данных, если вы работаете в laravel. Для этого вы создаете реальность между таблицами friend
и user
в базе данных, а также в моделях. Также вы должны использовать unique
в базе данных.
$data= array('accepted' => 0);
User::find($otherID)->friends()->updateOrCreate(['user_id', $otherID], $data));
Это запрос, с которым вы можете работать. Также вы можете передать несколько условий здесь. Благодаря
Ответ 5
Вы можете использовать методы firstOrCreate
/firstOrNew
(https://laravel.com/docs/5.3/eloquent)
Пример (из документов):
// Retrieve the flight by the attributes, or create it if it doesn't exist...
$flight = App\Flight::firstOrCreate(['name' => 'Flight 10']);
// Retrieve the flight by the attributes, or instantiate a new instance...
$flight = App\Flight::firstOrNew(['name' => 'Flight 10']);
Ответ 6
используйте `firstOrCreate ', он будет делать то же, что и вручную.
Определение FirstOrCreate, скопированное из руководства Laravel.
Метод FirstOrCreate попытается найти запись базы данных с использованием заданных пар столбца/значения. Если модель не может быть найдена в базе данных, запись будет вставлена с указанными атрибутами.
Итак, в соответствии с этим вы должны попробовать:
$user = User::where( 'id', '=', $otherID )->first();
$friend=Friend::firstOrCreate(['user_id' => $myId], ['user_2' => $otherId]);
Он будет проверять оба идентификатора, если они не существуют, а затем создать запись в таблице друзей.