Tenho uma relação muitos para muitos configurada e funcionando, para adicionar um item ao carrinho que utilizo:
$cart->items()->attach($item);
O que adiciona um item à tabela dinâmica (como deveria), mas se o usuário clicar no link novamente para adicionar um item que ele já adicionou, ele cria uma entrada duplicada na tabela dinâmica.
Existe uma maneira embutida de adicionar um registro a uma tabela dinâmica apenas se ainda não existir um?
Se não, como posso verificar a tabela dinâmica para descobrir se já existe um registro correspondente?
attach()
é misturado, pode ser um int ou uma instância do modelo;) - consulte github.com/laravel/framework/blob/master/src/Illuminate/…contains
instrução @bagusflyer verifica se a chave está presente em um objeto da coleção. Você deve ter um erro em seu código.$cart->items()->where('foreign_key', $foreignKey)->count()
Que, bem, na verdade também executa uma consulta adicional '^^ Mas eu não preciso buscar e hidrate a coleção inteira, a menos que eu realmente precise.exists()
função em vez decount()
para a melhor otimização.Você também pode usar o
$model->sync(array $ids, $detaching = true)
método e desativar a desconexão (o segundo parâmetro).Atualização: desde o Laravel 5.3 ou 5.2.44, você também pode chamar syncWithoutDetaching:
Que faz exatamente o mesmo, mas mais legível :)
fonte
$cart->items()->sync([1, 2, 3])
vai construir muitos-para-muitos relações com o id do na matriz dada,1
,2
, e3
, e delete (ou "desconexão") todos os outros id não é na matriz. Dessa forma, apenas os id's fornecidos no array existirão na tabela. Brilliant @Barryvdh usa um segundo parâmetro não documentado para desabilitar essa desconexão, portanto, nenhum relacionamento que não esteja no array fornecido é excluído, mas apenas ids exclusivos serão anexados. Verifique o documento "sincronização para conveniência". (Laravel 5.2)syncWithoutDetaching()
, que chama o sync () com false como segundo parâmetro.syncWithoutDetaching()
funcionou!O método @alexandre Butynsky funciona muito bem, mas usa duas consultas sql.
Um para verificar se o carrinho contém o item e outro para salvar.
Para usar apenas uma consulta, use:
fonte
Por melhores que sejam todas essas respostas porque eu tentei todas elas, uma coisa ainda ficou sem resposta ou não foi atendida: o problema de atualizar um valor previamente marcado (desmarcada a caixa marcada [es]). Eu tenho algo semelhante à pergunta acima, mas espero verificar e desmarcar os recursos dos produtos em minha tabela de recursos de produtos (a tabela dinâmica). Eu sou um novato e percebi que nenhuma das opções acima fazia isso. Ambos são bons para adicionar novos recursos, mas não quando eu quero remover recursos existentes (ou seja, desmarcá-lo)
Eu aprecio qualquer esclarecimento sobre isso.
ou
Desculpe pessoal, não tenho certeza se devo deletar a pergunta porque tendo descoberto a resposta sozinho, parece um pouco estúpido, bem, a resposta acima é tão simples quanto trabalhar @Barryvdh sync () da seguinte maneira; tendo lido cada vez mais sobre:
fonte
Você pode apenas usar
$cart->items()->sync($items)
A partir do Laravel 5.7:
fonte
Já existem ótimas respostas postadas. Eu queria jogar este aqui também.
As respostas de @AlexandreButynski e @Barryvdh são mais legíveis do que minha sugestão, o que essa resposta adiciona é alguma eficiência.
Ele recupera apenas as entradas para a combinação atual (na verdade, apenas o id) e, em seguida, anexa-o se não existir. O método de sincronização (mesmo sem desanexar) recupera todos os IDs atualmente anexados. Para conjuntos menores com pequenas iterações, isso dificilmente fará diferença, ... você entendeu.
De qualquer forma, definitivamente não é tão legível, mas funciona.
fonte