Comment faire pour supprimer plusieurs enregistrements à l'aide de Laravel Éloquent
Maintenant de cela, de ce que je vois, doit avoir été simple.
Je veux être en mesure de supprimer plusieurs enregistrements de la base de données. J'ai le id
's de tous les dossiers que je souhaite supprimer. J'appelle le resource.destroy
itinéraire à l'aide de liste séparée par des virgules de id (id
est de postgres type uuid
), comme suit:
Request URL:http://foo.app/products/62100dd6-7ecf-4870-aa79-4b132e60c904,c4b369f1-d1ef-4aa2-b4df-b9bc300a4ff5
Request Method:DELETE
Sur l'autre extrémité, mon contrôleur de l'action ressemble à ceci:
public function destroy($id)
{
try {
$ids = explode(",", $id);
$org->products()->find($ids)->delete();
}
catch(...) {
}
}
Cela me donne l'erreur suivante:
BadMethodCallException in Macroable.php line 81:
Method delete does not exist.
in Macroable.php line 81
at Collection->__call('delete', array()) in ProductsController.php line 251
at Collection->delete() in ProductsController.php line 251
at ProductsController->destroy('62100dd6-7ecf-4870-aa79-4b132e60c904,c4b369f1-d1ef-4aa2-b4df-b9bc300a4ff5')
J'ai vérifié que find()
est de retourner une collection de products
correspondant à l'id spécifié.
Ce qui me manque?
PS:
1. Le modèle Product
a plusieurs belongsTo
des relations avec d'autres modèles.
2. Le product.destroy
code fonctionne très bien si je passe un unique id
MODIFIER
Je suppose que je suis aussi en train d'essayer de comprendre quelle est la différence entre:
$org->products()->find($ids)->delete()
et
$org->products()->whereIn('id', $ids)->get()->delete()
est? De ce que je vois, à la fois find
et get
sont de retour Collections
destroy()
méthode?J'ai été à l'aide de ce thread comme référence. J'ai vu les documents que vous consultez. Je me sens un peu nerveux appel
Model::destroy
avec l'id de produit car un utilisateur malveillant peut supprimer des produits appartenant à d'autres orgs
(orgs
a beaucoup de products
). Je préfère d'abord trouver les enregistrements (basé sur organization
un utilisateur appartient), puis les supprimer. Je pourrais utiliser une boucle for (n
des requêtes). J'ai pu également utiliser un delete
requête avec in
clause. Je me demandais si il y a quelque chose de plus pratique et élégant.Je n'ai pas résolu encore. Voir mon commentaire ci-dessus pour les solutions que j'ai en tête.
Le problème est, comme quelqu'un l'a mentionné ci-dessous, que vous appelez delete() sur une collection par opposition à l'objet réel lui-même. à l'aide de votre exemple, vous pouvez effectuer les opérations suivantes:
$org->products()->find($ids)->each(function($product){ $product->delete(); });
OriginalL'auteur Code Poet | 2016-01-27
Vous devez vous connecter pour publier un commentaire.
Le problème est que vous êtes d'appel
delete()
sur une Collection, qui n'a pas cette méthode.Vous avez deux options ici.
Modèle Événements
Si vous avez des écouteurs d'événement pour l'
deleting
/deleted
événements du modèle, vous devez vous assurer que la suppression se produit de manière à ce que chaque modèle est chargé, puis supprimé.Dans ce cas, vous pouvez utiliser le
destroy
méthode sur le modèle qui prend une liste d'id. Il va charger un nouveau modèle pour chaque id, et ensuite appelerdelete()
sur elle. Comme vous l'avez mentionné dans un commentaire, il ne sera pas restreindre la suppression de seulement ces produits dans l'organisme, de sorte que vous devez filtrer les codes avant de passer à la liste dans ledestroy()
méthode.Si vous n'avez pas particulièrement cette approche, vous aurez besoin pour effectuer une itération de votre collection d'organisation et de produits d'appel
delete()
sur eux individuellement. Vous pouvez utiliser un standardforeach
, ou vous pouvez utiliser leeach
méthode sur la collection:Pas De Modèle Événements
Maintenant, si vous n'avez pas de modèle d'événements que vous devez écouter, les choses sont un peu plus facile. Dans ce cas, vous pouvez simplement appeler
delete()
sur le générateur de requête, et il va aller tout droit pour supprimer les enregistrements sans le chargement de tous les objets de modèle. Ainsi, vous obtenez plus propre code avec de meilleures performances:OriginalL'auteur patricus
J'ai aussi été confronté à ce problème. Laissez
$orgs
contient des enregistrements d'une collection. Maintenant, vous pouvez facilement supprimer ces enregistrements à l'aide d'une boucle comme celle-ci,OriginalL'auteur Md. Farhan Sadique Ranok
Lorsque vous utilisez la méthode de recherche, il se trouve seulement une ID unique. Vous devez utiliser un où pour correspondre à de multiples identifiants
De cette façon, vous trouverez tous les produits d'Id et de tous les supprimer.
find()
prend en charge un tableau d'id. Ce n'est pas documentée, mais vous pouvez prendre un coup d'oeil à la source github.com/laravel/framework/blob/5.1/src/Illuminate/Database/...Oui, vous avez raison. Et il en fait de même... un dans lequel.
méthode find() parfois ne prend pas en charge plusieurs id, vous pouvez à la place utiliser findMany($id). Et encore une chose, findMany() ainsi que la méthode find() ne dispose pas de méthode delete ().
Vous ne pouvez pas utiliser get() et delete ().
OriginalL'auteur Andrés Smerkin