У меня есть модель Eloquent, у которой есть связанная модель:
public function option() {
return $this->hasOne('RepairOption', 'repair_item_id');
}
public function setOptionArrayAttribute($values)
{
$this->option->update($values);
}
Когда я создаю модель, она не обязательно имеет связанную модель. Когда я обновляю его, я могу добавить опцию или нет.
Поэтому мне нужно проверить, существует ли связанная модель, обновить или создать ее соответственно:
$model = RepairItem::find($id);
if (Input::has('option')) {
if (<related_model_exists>) {
$option = new RepairOption(Input::get('option'));
$option->repairItem()->associate($model);
$option->save();
$model->fill(Input::except('option');
} else {
$model->update(Input::all());
}
};
Где <related_model_exists>
код, который я ищу.
Ответы:
В php 7.2+ вы не можете использовать
count
объект отношения, поэтому не существует универсального метода для всех отношений. Вместо этого используйте метод запроса как @tremby, представленный ниже:универсальное решение, работающее со всеми типами отношений ( pre php 7.2 ):
Это будет работать для каждого отношения, так как динамические свойства возвращают
Model
илиCollection
. Оба реализуютArrayAccess
.Итак, это выглядит так:
одиночные отношения:
hasOne
/belongsTo
/morphTo
/morphOne
отношения ко многим:
hasMany
/belongsToMany
/morphMany
/morphToMany
/morphedByMany
источник
count($relation)
это общее решение для всех отношений. Это будет работатьModel
иCollection
, покаModel
не имеет->count()
метода.Collection
имеет свой собственный методisEmpty
, но универсальнаяempty
функция возвращает false для объекта (поэтому не будет работать для пустой коллекции).count($model->relation)
не работал,morphTo
когда отношения еще не были установлены. Иностранный идентификатор и тип являются нулевыми, и запрос БД, созданный Laravel, является поддельным и вызывает исключение. Я использовал$model->relation()->getOtherKey()
в качестве обходного пути.count(): Parameter must be an array or an object that implements Countable
Объект Relation передает вызовы неизвестного метода в построитель запросов Eloquent , который настроен на выбор только связанных объектов. Этот Builder, в свою очередь, передает вызовы неизвестных методов своему базовому построителю запросов .
Это означает, что вы можете использовать методы
exists()
илиcount()
напрямую из объекта отношения:Обратите внимание на круглые скобки после
relation
:->relation()
это вызов функции (получение объекта отношения), в отличие от->relation
которого Laravel установил для вас средство получения магического свойства (получение связанного объекта / объектов).Использование
count
метода для объекта отношения (то есть использование скобок) будет намного быстрее, чем выполнение$model->relation->count()
илиcount($model->relation)
(если отношение не было уже загружено), поскольку он выполняет запрос подсчета, а не извлекает все данные для любых связанных объектов из базы данных, просто посчитать их. Аналогично, использованиеexists
не требует извлечения данных модели.Как
exists()
иcount()
работа на всех типах реляционных я пробовал, так что, по крайней мереbelongsTo
,hasOne
,hasMany
иbelongsToMany
.источник
Я предпочитаю использовать
exists
метод:RepairItem::find($id)->option()->exists()
проверить, существует ли связанная модель или нет. На Laravel 5.2 работает нормально
источник
После Php 7.1 принятый ответ не будет работать для всех типов отношений.
Поскольку в зависимости от типа отношения, Eloquent возвращает a
Collection
, aModel
илиNull
. И в Php 7.1count(null)
добавлюerror
.Итак, чтобы проверить, существует ли отношение, вы можете использовать:
Для одиноких отношений: например
hasOne
иbelongsTo
Для отношений несколько: например:
hasMany
иbelongsToMany
источник
Не уверен, что это изменилось в Laravel 5, но использование принятого ответа
count($data->$relation)
не сработало для меня, так как сам доступ к свойству отношения вызвал его загрузку.В конце концов, простой
isset($data->$relation)
сделал свое дело для меня.источник
$data->relation
без$
(не может редактировать, из-за ограничения в 6 символов)$relation
будет имя вашего отношения, например,$data->posts
или как , как. Извините, если это сбивает с толку, я хотел прояснить, чтоrelation
это не конкретное свойство модели: PВы можете использовать relationLoaded метод на модели объекта. Это спасло мой бекон, надеюсь, это поможет кому-то еще. Мне дали это предложение, когда я задал тот же вопрос на Laracasts.
источник
Как уже сказал Хемерсон Варела в Php 7.1,
count(null)
он выдаетerror
иhasOne
возвращает,null
если строки не существует. Поскольку у вас естьhasOne
отношение, я бы использовалempty
метод для проверки:Но это лишнее. Нет необходимости проверять, существует ли эта связь, чтобы определить, следует ли вам позвонить
update
илиcreate
позвонить. Просто используйте метод updateOrCreate . Это эквивалентно приведенному выше:источник
Мне пришлось полностью реорганизовать мой код, когда я обновил свою версию PHP до 7.2+ из-за неправильного использования функции count ($ x). Это настоящая боль, и это также очень страшно, потому что есть сотни способов использования в разных сценариях, и нет единого правила, подходящего для всех ..
Правила, которым я следовал, чтобы изменить все, примеры:
$ x = Auth :: user () -> posts-> find (6); (проверьте, есть ли у пользователя идентификатор сообщения = 6, используя -> find ())
$ x = Auth :: user () -> profile-> департаменты; (проверьте, есть ли в профиле несколько отделов, может быть много отделов)
$ x = Auth :: user () -> profile-> get (); (проверьте, есть ли у пользователя профиль после использования -> get ())
Надеюсь, что это может помочь, даже через 5 лет после того, как вопрос был задан, эта статья о переполнении стека очень мне помогла!
источник