Je souhaite récupérer le dernier fichier inséré dans ma table. Je sais que la méthode first()existe et vous fournit le premier fichier du tableau mais je ne sais pas comment obtenir le dernier insert.
Ceci est pour toute personne demandant et répondant à propos de Laravel. N'oubliez pas qu'il est important de spécifier de quelle version de Laravel vous parlez. En général, les versions 4 et 5 présentent des différences et les anciennes versions aussi.
Heroselohim
Réponses:
224
Vous devrez classer par le même champ que vous commandez maintenant, mais en ordre décroissant. Par exemple, si vous avez un horodatage lorsque le téléchargement a été appelé upload_time, vous feriez quelque chose comme ceci;
Cela ordonnera les lignes de la table des fichiers par heure de téléchargement, ordre décroissant et prendra la première. Ce sera le dernier fichier téléchargé.
Pour Laravel 4, cela devrait être orderBy, pasorder_by
Jared Eitnier
9
Lorsque vous utilisez ORM, c'est une manière correcte:User::orderby('created_at', 'desc')->first();
Cas Bloem
1
Laravel 5.x =orderBy('created_at', 'desc')
0x1ad2
9
Pourquoi utilisez-vous la colonne created_at? Beaucoup plus rapide à utiliser l'ID de clé primaire. Laravel 5.x Files::orderBy(id', 'desc')->first();Trier par date fonctionne plus longtemps car la date est une chaîne et probablement non indexée. Alors que la clé primaire est indexée et fonctionne très rapidement. Même si created_at est indexé, il s'agit d'une chaîne indexée et non de INT en cas de primaire. La chaîne d'index a moins de performances.
KorbenDallas
4
Le commentaire @KorbenDallas devrait être la réponse car parfois orderBy('created_at', 'desc')ne vous donne pas la dernière ligne. Exemple: 3 lignes peuvent avoir exactement la même valeur TIMESTAMP et avec orderBy('created_at', 'desc')vous obtiendrez la première des 3 (qui n'est pas nécessairement la dernière ligne)
viery365
111
Utilisez la dernière portée fournie par Laravel hors de la boîte.
Model::latest()->first();
De cette façon, vous ne récupérez pas tous les enregistrements. Un raccourci plus agréable pour orderBy.
Notez que cette méthode utilise la created_atcolonne auto-générée ($timestamps = true)dans le modèle, mais peut être désactivée à souhait pour que vous ayez une erreur si non définie
Plotisateur
J'utilise Laravel 5.7 et j'essaie de le faire sur un modèle récupère toujours tous les enregistrements pour moi.
CJ Dennis
1
Notez que si vous avez plusieurs enregistrements ajoutés dans la même seconde, l'heure created_at sera la même pour ces enregistrements et par conséquent, l'enregistrement renvoyé par latest () peut ne pas être l'enregistrement que vous attendez.
F3CP
Notez que vous n'avez pas besoin d'une colonne «created_at». Vous pouvez spécifier à partir de quelle colonne vous voulez la dernière. Par exemple: Model :: latest ('dateColumn') -> first ();
Tom
Cela peut ne pas obtenir la dernière ligne réelle si deux lignes sont insérées dans un délai de 1 seconde (cela a en fait causé des problèmes dans les tests unitaires).
chili
75
Vous n'avez jamais mentionné si vous utilisiez Eloquent, l'ORM par défaut de Laravel ou non. Dans le cas où vous l'êtes, disons que vous voulez obtenir la dernière entrée d'une table User, par created_at, vous pourriez probablement faire comme suit:
User::orderBy('created_at','desc')->first();
Tout d'abord, il classe les utilisateurs par champ created_at, par ordre décroissant, puis il prend le premier enregistrement du résultat.
Cela vous renverra une instance de l'objet User, pas une collection. Bien sûr, pour utiliser cette alternative, vous devez avoir un modèle User, étendant la classe Eloquent. Cela peut sembler un peu déroutant, mais il est vraiment facile de commencer et ORM peut être vraiment utile.
Pour plus d'informations, consultez la documentation officielle qui est assez riche et bien détaillée.
Je voulais juste souligner que la all()méthode charge en fait tous les éléments. Cela ne fonctionnera pas sur une table avec des millions d'enregistrements.
Steven Jeffries
1
En plus du commentaire de Steven Jeffries, je voudrais souligner que l'appel last()renvoie une seule instance Eloquent et non une collection, et appeler pluck()cela équivaut à appeler Model::all()->pluck('name'), donc renvoyer l' nameattribut de toutes les lignes de la table
ivcandela
5
Cette méthode est pire en fait. Vous récupérez le dernier brut en utilisant l'exécution PHP au lieu de le faire au niveau de la base de données. Et si la table contient des millions de matières premières, alors vous savez à quel point elle peut être inefficace?
Bhaskar Dabhi
C'est la meilleure façon de procéder. - Non! Cela n'a jamais été, ne le sera jamais. Vous chargez toutes les lignes au lieu de celle dont vous avez besoin.
Cela renverra plusieurs lignes. Il a besoin d'une seule rangée. first () l'aidera avec la clause orderBy ().
Tahir Afridi
Cela peut ne pas obtenir la dernière ligne réelle si deux lignes sont insérées dans un délai de 1 seconde (cela a en fait causé des problèmes dans les tests unitaires).
chili
1
Sur une grande table, cela provoquera une exception de mémoire insuffisante car, comme @TahirAfridi l'a mentionné, cela chargera toutes les lignes en mémoire.
Rihards
6
Vous pouvez utiliser la dernière portée fournie par Laravel avec le champ que vous souhaitez filtrer, disons qu'il sera trié par ID, puis:
Model::latest('id')->first();
Ainsi, vous pouvez éviter de commander par created_atchamp par défaut chez Laravel.
Fonctionne aussi pour moi dans Laravel 5.8, je viens de poster la réponse avant de voir la vôtre
Dazzle
1
Une petite explication sur la façon dont laravel fait cela dans les coulisses et pourquoi cela est dangereux pour un grand ensemble de données, la get()méthode récupérera tout your_tableet générera une collection et la last()méthode obtiendra le dernier élément de cette collection. Donc, vous aurez déjà toutes les données de la table chargées sur votre mémoire (mauvaise). Vous devez simplement utiliser `DB :: table ('items') -> latest () -> first ();` derrière la scène, il exécute `orderBy ($ column, 'desc')` et récupère le premier enregistrement.
Si vous recherchez la ligne réelle que vous venez d'insérer avec Laravel 3 et 4 lorsque vous effectuez une action saveou createsur un nouveau modèle comme:
puis l'instance de modèle insérée sera retournée et pourra être utilisée pour d'autres actions telles que la redirection vers la page de profil de l'utilisateur qui vient d'être créé.
La recherche du dernier enregistrement inséré fonctionne sur un système à faible volume fonctionnera presque tout le temps, mais si jamais vous devez insérer des insertions en même temps, vous pouvez finir par interroger pour trouver le mauvais enregistrement. Cela peut vraiment devenir un problème dans un système transactionnel où plusieurs tables doivent être mises à jour.
D'une manière ou d'une autre, tout ce qui précède ne semble pas fonctionner pour moi dans laravel 5.3, j'ai donc résolu mon propre problème en utilisant:
Utilisez- Model::where('user_id', $user_id)->latest()->get()->first();
le ne retournera qu'un seul enregistrement, s'il n'est pas trouvé, il retournera null. J'espère que cela aidera.
Si la table a un champ de date, c'est ( User::orderBy('created_at', 'desc')->first();) la meilleure solution, je pense. Mais il n'y a pas de champ de date, Model ::orderBy('id', 'desc')->first()->id;c'est la meilleure solution, j'en suis sûr.
soyez conscient que last(), latest()ne sont pas déterministes si vous recherchez un enregistrement séquentiel ou événement / ordonné. Les derniers enregistrements / récents peuvent avoir exactement le même created_athorodatage, et que vous récupérez n'est pas déterministe. Alors fais orderBy(id|foo)->first(). D'autres idées / suggestions sur la façon d'être déterministe sont les bienvenues.
Réponses:
Vous devrez classer par le même champ que vous commandez maintenant, mais en ordre décroissant. Par exemple, si vous avez un horodatage lorsque le téléchargement a été appelé
upload_time
, vous feriez quelque chose comme ceci;Pour Pre-Laravel 4
Pour Laravel 4 et plus
Pour Laravel 5.7 et versions ultérieures
Cela ordonnera les lignes de la table des fichiers par heure de téléchargement, ordre décroissant et prendra la première. Ce sera le dernier fichier téléchargé.
la source
orderBy
, pasorder_by
User::orderby('created_at', 'desc')->first();
orderBy('created_at', 'desc')
Files::orderBy(id', 'desc')->first();
Trier par date fonctionne plus longtemps car la date est une chaîne et probablement non indexée. Alors que la clé primaire est indexée et fonctionne très rapidement. Même si created_at est indexé, il s'agit d'une chaîne indexée et non de INT en cas de primaire. La chaîne d'index a moins de performances.orderBy('created_at', 'desc')
ne vous donne pas la dernière ligne. Exemple: 3 lignes peuvent avoir exactement la même valeur TIMESTAMP et avecorderBy('created_at', 'desc')
vous obtiendrez la première des 3 (qui n'est pas nécessairement la dernière ligne)Utilisez la dernière portée fournie par Laravel hors de la boîte.
De cette façon, vous ne récupérez pas tous les enregistrements. Un raccourci plus agréable pour orderBy.
la source
created_at
colonne auto-générée($timestamps = true)
dans le modèle, mais peut être désactivée à souhait pour que vous ayez une erreur si non définieVous n'avez jamais mentionné si vous utilisiez Eloquent, l'ORM par défaut de Laravel ou non. Dans le cas où vous l'êtes, disons que vous voulez obtenir la dernière entrée d'une table User, par created_at, vous pourriez probablement faire comme suit:
Tout d'abord, il classe les utilisateurs par champ created_at, par ordre décroissant, puis il prend le premier enregistrement du résultat.
Cela vous renverra une instance de l'objet User, pas une collection. Bien sûr, pour utiliser cette alternative, vous devez avoir un modèle User, étendant la classe Eloquent. Cela peut sembler un peu déroutant, mais il est vraiment facile de commencer et ORM peut être vraiment utile.
Pour plus d'informations, consultez la documentation officielle qui est assez riche et bien détaillée.
la source
Pour obtenir les détails du dernier enregistrement
Model::all()->last();
ouModel::orderBy('id', 'desc')->first();
Pour obtenir l'identifiant du dernier enregistrement
Model::all()->last()->id;
ouModel::orderBy('id', 'desc')->first()->id;
la source
Les collections Laravel ont la dernière méthode
C'est la meilleure façon de procéder.
la source
all()
méthode charge en fait tous les éléments. Cela ne fonctionnera pas sur une table avec des millions d'enregistrements.last()
renvoie une seule instance Eloquent et non une collection, et appelerpluck()
cela équivaut à appelerModel::all()->pluck('name')
, donc renvoyer l'name
attribut de toutes les lignes de la tableEssaye ça :
la source
Vous pouvez utiliser la dernière portée fournie par Laravel avec le champ que vous souhaitez filtrer, disons qu'il sera trié par ID, puis:
Ainsi, vous pouvez éviter de commander par
created_at
champ par défaut chez Laravel.la source
Pour obtenir les détails du dernier enregistrement, utilisez le code ci-dessous:
la source
Une autre façon sophistiquée de le faire dans Laravel 6.x (Incertain mais doit également fonctionner pour 5.x):
DB::table('your_table')->get()->last();
Vous pouvez également accéder aux champs:
DB::table('your_table')->get()->last()->id;
la source
get()
méthode récupérera toutyour_table
et générera une collection et lalast()
méthode obtiendra le dernier élément de cette collection. Donc, vous aurez déjà toutes les données de la table chargées sur votre mémoire (mauvaise). Vous devez simplement utiliser `DB :: table ('items') -> latest () -> first ();` derrière la scène, il exécute `orderBy ($ column, 'desc')` et récupère le premier enregistrement.Model($where)->get()->last()->id
la source
Si vous recherchez la ligne réelle que vous venez d'insérer avec Laravel 3 et 4 lorsque vous effectuez une action
save
oucreate
sur un nouveau modèle comme:-ou-
puis l'instance de modèle insérée sera retournée et pourra être utilisée pour d'autres actions telles que la redirection vers la page de profil de l'utilisateur qui vient d'être créé.
La recherche du dernier enregistrement inséré fonctionne sur un système à faible volume fonctionnera presque tout le temps, mais si jamais vous devez insérer des insertions en même temps, vous pouvez finir par interroger pour trouver le mauvais enregistrement. Cela peut vraiment devenir un problème dans un système transactionnel où plusieurs tables doivent être mises à jour.
la source
D'une manière ou d'une autre, tout ce qui précède ne semble pas fonctionner pour moi dans laravel 5.3, j'ai donc résolu mon propre problème en utilisant:
j'espère pouvoir renflouer quelqu'un.
la source
Utilisez-
Model::where('user_id', $user_id)->latest()->get()->first();
le ne retournera qu'un seul enregistrement, s'il n'est pas trouvé, il retourneranull
. J'espère que cela aidera.la source
Si la table a un champ de date, c'est (
User::orderBy('created_at', 'desc')->first();
) la meilleure solution, je pense. Mais il n'y a pas de champ de date,Model ::orderBy('id', 'desc')->first()->id;
c'est la meilleure solution, j'en suis sûr.la source
soyez conscient que
last()
,latest()
ne sont pas déterministes si vous recherchez un enregistrement séquentiel ou événement / ordonné. Les derniers enregistrements / récents peuvent avoir exactement le mêmecreated_at
horodatage, et que vous récupérez n'est pas déterministe. Alors faisorderBy(id|foo)->first()
. D'autres idées / suggestions sur la façon d'être déterministe sont les bienvenues.la source