Подтвердить что ты не робот

Как упростить этот код 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();
    }
}
4b9b3361

Ответ 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]);    

Он будет проверять оба идентификатора, если они не существуют, а затем создать запись в таблице друзей.