Я хочу использовать функцию 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?
СПАСИБО.
нет, я проверял это раньше, но это другой вопрос. Мой вопрос: как проверить отношение в методе firstOrCreate, связанный вопрос: как использовать метод findOrCreate через отношение.






Сначала в защищенном поле $ fillable вы подчеркнули поле нация, относящееся к БД. В соответствии с этим я не понимаю поле nation_id во втором запросе попытки.
В объявлении отношения подчеркните внешний ключ, чтобы стало ясно различие между двумя полями (nation и nation_id).
Предполагая, что поле нация содержит отношение к записи Наций (отношение соответствия по первичному уникальному идентификатору), вы можете сравнивать предоставленные данные по этому идентификатору (для сравнения наций), а не по всем полям страны.
Тогда первый случай, о котором вы сообщили, я предположил, ошибочен
First case: "Nation_id doesn't have a default value"
потому что это означает, что вы вставляете спортсмена без предоставления идентификатора нации, и, следовательно, этот идентификатор не проверяется в построителе запросов (возможно, потому что он равен нулю). Таким образом, вы не увидите сравнение с текущим спортсменом и существующим спортсменом db, если нация не указана.
В общем, я предлагаю вам сделать следующие шаги для выполнения вашей задачи:
Напишите запрос таким образом
$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.
да, не используйте отношение sql, но с проверкой правильности установки отношений в таблицах я имею в виду следующее: 1. явно объявите ключ, в котором laravel устанавливает отношение return $ this-> hasOne ('App \ Athlete', 'foreign_key '); 2. сначала попробуйте разделить этапы, выполняемые функцией FirstOrCreate, создав запрос выбора, чтобы найти количество строк, равных входным данным, а затем вставьте запрос, если это количество равно 0. Это позволит вам убедиться, что Laravel правильно распознает связь.
$fillable должен содержать имя столбца, а не имя отношения. Также отсутствует sex:
protected $fillable = ['firstname', 'lastname', 'sex', 'nation_id'];
Возможный дубликат Laravel Eloquent - firstOrCreate () для отношений