Eu tenho um modelo eloquente que tem um modelo relacionado:
public function option() {
return $this->hasOne('RepairOption', 'repair_item_id');
}
public function setOptionArrayAttribute($values)
{
$this->option->update($values);
}
Quando crio o modelo, ele não tem necessariamente um modelo relacionado. Quando atualizá-lo, posso adicionar uma opção ou não.
Portanto, preciso verificar se o modelo relacionado existe, para atualizá-lo ou criá-lo, respectivamente:
$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());
}
};
Onde <related_model_exists>
está o código que estou procurando?
Respostas:
No php 7.2+ você não pode usar
count
o objeto de relação, portanto, não existe um método único para todas as relações. Use o método de consulta como @tremby fornecido abaixo:solução genérica trabalhando em todos os tipos de relação ( pré php 7.2 ):
Isso funcionará para todas as relações, pois as propriedades dinâmicas retornam
Model
ouCollection
. Ambos implementamArrayAccess
.Então é assim:
relações únicas:
hasOne
/belongsTo
/morphTo
/morphOne
relações com muitos:
hasMany
/belongsToMany
/morphMany
/morphToMany
/morphedByMany
fonte
count($relation)
é uma solução geral para todas as relações. Ele funcionará paraModel
eCollection
, enquantoModel
não tiver->count()
método.Collection
possui seu próprio métodoisEmpty
, mas aempty
função genérica retorna false para um objeto (portanto, não funciona para a coleção vazia).count($model->relation)
não funcionoumorphTo
quando o relacionamento ainda não tinha uma associação definida. ID e tipo externos são nulos e a consulta db criada pelo Laravel é falsa e gera exceção. Eu usei$model->relation()->getOtherKey()
como solução alternativa.count(): Parameter must be an array or an object that implements Countable
Um objeto Relation transmite chamadas de método desconhecidas para um Eloquent query Builder , configurado para selecionar apenas os objetos relacionados. Esse construtor, por sua vez, transmite chamadas de método desconhecido para o construtor de consultas subjacente .
Isso significa que você pode usar os métodos
exists()
oucount()
diretamente de um objeto de relação:Observe os parênteses depois de
relation
:->relation()
é uma chamada de função (obtendo o objeto de relação), em vez de->relation
um getter de propriedades mágicas configurado para você pelo Laravel (obtendo o objeto / objetos relacionados).Usar o
count
método no objeto de relação (ou seja, usar parênteses) será muito mais rápido do que fazer$model->relation->count()
oucount($model->relation)
(a menos que a relação já tenha sido carregada com antecedência), pois executa uma consulta de contagem em vez de extrair todos os dados de quaisquer objetos relacionados do banco de dados, apenas para contá-los. Da mesma forma, o usoexists
também não precisa extrair dados do modelo.Ambos
exists()
ecount()
trabalho em todos os tipos de relação que eu tentei, por isso, pelo menosbelongsTo
,hasOne
,hasMany
, ebelongsToMany
.fonte
Eu prefiro usar o
exists
método:RepairItem::find($id)->option()->exists()
para verificar se o modelo relacionado existe ou não. Está funcionando bem no Laravel 5.2
fonte
Após o Php 7.1 , a resposta aceita não funcionará para todos os tipos de relacionamentos.
Porque, dependendo do tipo do relacionamento, o Eloquent retornará a
Collection
, aModel
ouNull
. E no Php 7.1count(null)
lançará umerror
.Portanto, para verificar se a relação existe, você pode usar:
Para relacionamentos únicos: por exemplo
hasOne
ebelongsTo
Para relacionamentos múltiplos: por exemplo:
hasMany
ebelongsToMany
fonte
Não tenho certeza se isso mudou no Laravel 5, mas a resposta aceita usando
count($data->$relation)
não funcionou para mim, pois o próprio ato de acessar a propriedade de relação fez com que ela fosse carregada.No final, um simples
isset($data->$relation)
fez o truque para mim.fonte
$data->relation
sem$
(não pode editar, porque de 6 caracteres limite)$relation
seria o nome da sua relação, assim$data->posts
ou não. Desculpe se isso foi confuso, eu queria deixar claro querelation
não era uma propriedade modelo concreto: PVocê pode usar o método relacionLoaded no objeto de modelo. Isso salvou meu bacon e espero que ajude outra pessoa. Recebi essa sugestão quando fiz a mesma pergunta em Laracasts.
fonte
Como Hemerson Varela já disse no Php 7.1
count(null)
, lançará umerror
ehasOne
retornaránull
se não houver linha. Como você tem umahasOne
relação, eu usaria oempty
método para verificar:Mas isso é supérfluo. Não há necessidade de verificar se a relação existe, para determinar se você deve fazer uma
update
ou umacreate
chamada. Basta usar o método updateOrCreate . Isso é equivalente ao acima:fonte
Eu tive que refatorar completamente meu código quando atualizei minha versão do PHP para 7.2+ devido ao mau uso da função count ($ x). Isso é uma verdadeira dor e também é extremamente assustador, pois existem centenas de usos, em diferentes cenários e não há regras para todos.
Regras que segui para refatorar tudo, exemplos:
$ x = Auth :: user () -> posts-> find (6); (verifique se o usuário tem um ID de postagem = 6 usando -> find ())
$ x = Auth :: user () -> perfil-> departamentos; (verifique se o perfil tem alguns departamentos, pode haver muitos departamentos)
$ x = Auth :: user () -> perfil-> get (); (verifique se o usuário tem um perfil depois de usar um -> get ())
Espero que isso possa ajudar, mesmo 5 anos após a pergunta, este post do stackoverflow me ajudou muito!
fonte