Laravel firstOrCreate search for Relationship

Я хочу использовать функцию firstOrCreate для Eloquent. Соответствующая часть моих данных - это спортсмены, принадлежащие к стране или стране, у которой есть много спортсменов. (Отношение один ко многим)

class Athlete extends Model
{
  public $timestamps = false;
  protected $fillable = ['firstname', 'lastname', 'nation'];
.....
  public function nation()
  {
      return $this->belongsTo('App\Nation');
  }
}

а также

class Nation extends Model
{
  public $timestamps = false;
...
  public function athletes()
  {
      return $this->hasMany('App\Athlete');
  }
}

Как я могу использовать firstOrCreate, если мне также нужно проверить нацию?

Ни один

$ath = Athlete::firstOrCreate(['nation_id'=>$nation->id, 'lastname'=>$nn, 'sex'=>$sex, 'firstname'=>$vn] );

ни

$ath = Athlete::firstOrCreate(['nation'=>$nation, 'lastname'=>$nn, 'sex'=>$sex, 'firstname'=>$vn] );

Работа.

Первый случай:

"Nation_id doesn't have a default value"

Второй случай:

Laravel tries to build a WHERE statement with the passed object, which obviously doesn't work.

Могу ли я использовать здесь firstOrCreate?

СПАСИБО.

Возможный дубликат Laravel Eloquent - firstOrCreate () для отношений

pspatel 30.05.2018 11:48

нет, я проверял это раньше, но это другой вопрос. Мой вопрос: как проверить отношение в методе firstOrCreate, связанный вопрос: как использовать метод findOrCreate через отношение.

gnarf 30.05.2018 14:47
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
2
992
2

Ответы 2

Сначала в защищенном поле $ fillable вы подчеркнули поле нация, относящееся к БД. В соответствии с этим я не понимаю поле nation_id во втором запросе попытки.

В объявлении отношения подчеркните внешний ключ, чтобы стало ясно различие между двумя полями (nation и nation_id).

Предполагая, что поле нация содержит отношение к записи Наций (отношение соответствия по первичному уникальному идентификатору), вы можете сравнивать предоставленные данные по этому идентификатору (для сравнения наций), а не по всем полям страны.

Тогда первый случай, о котором вы сообщили, я предположил, ошибочен

First case: "Nation_id doesn't have a default value"

потому что это означает, что вы вставляете спортсмена без предоставления идентификатора нации, и, следовательно, этот идентификатор не проверяется в построителе запросов (возможно, потому что он равен нулю). Таким образом, вы не увидите сравнение с текущим спортсменом и существующим спортсменом db, если нация не указана.

В общем, я предлагаю вам сделать следующие шаги для выполнения вашей задачи:

  1. Проверьте, правильно ли переданы все данные, переданные в построитель запросов.
  2. Напишите запрос таким образом

    $ath = Athlete::firstOrCreate(['field_that_contains_nation_id'=>$nation->id, 'other_athlete_fields' => $value, ...] );
    

    затем запустите операцию для этой модели

    $ath->save();
    

    если вы хотите знать, создана ли запись, сделайте следующее:

    if ($ath->wasRecentlyCreated){
        echo 'Created successfully';
    } else {
        echo 'Already exist';
    }
    

Если это уже не работает, проверьте, правильно ли установлены отношения в таблицах.

Я использую стандартное именование Laravel (надеюсь), связанный объект называется «нация». Итак, Laravel использует столбец mysql "nation_id" в качестве внешнего ключа. В переменной $ nation у меня есть объект, поэтому я попытался (как вы предложили) сравнить идентификаторы. (Мой первый пример в исходном вопросе) Что вы имеете в виду под правильной установкой отношения? В моих моделях у меня есть отношения (см. Исходный вопрос). В таблицах mysql у меня есть поле «id» в обеих таблицах и «nation_id» в качестве внешнего ключа. Все стандартные наименования Laravel. Я не использую отношения mysql, потому что отношения должны обрабатываться laravel.

gnarf 30.05.2018 14:45

да, не используйте отношение sql, но с проверкой правильности установки отношений в таблицах я имею в виду следующее: 1. явно объявите ключ, в котором laravel устанавливает отношение return $ this-> hasOne ('App \ Athlete', 'foreign_key '); 2. сначала попробуйте разделить этапы, выполняемые функцией FirstOrCreate, создав запрос выбора, чтобы найти количество строк, равных входным данным, а затем вставьте запрос, если это количество равно 0. Это позволит вам убедиться, что Laravel правильно распознает связь.

Matteo Conti 31.05.2018 10:11

$fillable должен содержать имя столбца, а не имя отношения. Также отсутствует sex:

protected $fillable = ['firstname', 'lastname', 'sex', 'nation_id'];

Другие вопросы по теме