Obtenir l'ID de Rails de Modèle avant de l'enregistrer...?
Comment obtenez-vous l'id d'un des rails de modèle avant de l'enregistrer?
Par exemple, si je crée une nouvelle instance du modèle, comment puis-je obtenir sa carte d'identité avant il est sauvé?
Je sais que l'id est créé onsave et selon la base de données, mais est-il une solution?
Quelqu'un avec plus de connaissances sur les Rails peuvent le confirmer, mais en général, le code est généré par la base de données donc aucun moyen de savoir ce que c'est jusqu'à l'insertion de la ligne. Vous pouvez bien sûr générer des Identifiants de vous-même, mais qui ouvre une boîte de pandore...
OriginalL'auteur amaseuk | 2010-08-12
Vous devez vous connecter pour publier un commentaire.
Généralement lorsque les gens pensent qu'ils ont besoin pour ce faire, ils n'ont pas besoin de le faire. Comme le dit Jean, expliquer ce que vous essayez de faire et que quelqu'un peut probablement suggérer un moyen de le faire sans avoir à connaître le numéro d'identification à l'avance.
Pouvez-vous svp m'indiquer un lien où je peux lire sur le rail de façon à le faire ?
OriginalL'auteur Max Williams
Je cherchais ce trop, et j'ai trouvé une réponse:
Supposons que le nom du modèle est "Modèle" et le nom de la table est "modèles"
modèle.rb
Ce sera la sortie de la valeur de votre dossier prendra l'identité de la il est sauvé de
thread-safe
, ce qui signifie que deux processus simultanés permettra d'acquérir le même id et ensuite l'utiliser.Vous pouvez incrémenter manuellement la seq, ce n'est pas une bonne pratique, mais il y a des thread-safe moyens à mettre en œuvre.
Ce doit être thread-safe comme-est;
nextval
incréments de la séquence et retourne la nouvelle valeur de manière atomique (postgresql.org/docs/8.1/static/functions-sequence.html)OriginalL'auteur Ruby Racer
À l'aide de la valeur par défaut convention Rails d'une auto-incrémentation integer primary key, il n'y a aucun moyen d'obtenir l'ID d'un modèle avant de le sauvegarder car elle est générée par le SGBD lors de la nouvelle ligne est insérée dans la table correspondante.
Ce problème êtes-vous en train d'essayer de résoudre?
OriginalL'auteur John Topley
C'est moins une des Rails de question et plus d'une base de données en question. C'est un problème qui va se présenter dans n'importe quelle application web framework, et la solution est la même dans tous les endroits. Vous devez utiliser une transaction de base de données.
Le flux de base fonctionne comme ceci.
La principale chose que vous remarquerez à partir de cette approche est qu'il y aura des lacunes dans vos Identifiants lorsque vous avez obtenu la transaction.
OriginalL'auteur haydenmuhl
La plupart du temps quand j'ai besoin d'un id peuvent être regroupées en une courte liste.
Lors de la création de imbriqués les associations ou relation des associations à travers.
Imaginons que nous avons:
:user
qui ont:pets
par:user_pets
association, où nous allons enregistrer leur type.Si nous avons correctement configuré "has_many: grâce à l'Association" nous pouvons tout simplement
User.pets.create(name: "Rex")
mais c'est trop simpliste, car nous voulons créer:pet
type dans:user_pets
.Vous avez vu comment cela a créé tous les id pour nous? Passons à quelque chose d'encore plus complexe!
Maintenant, nous avons une table supplémentaire
:shampoo
exactement comme:user_pet
, appartient à une:pet
et un:user
Nous avons besoin de créer sans le savoir l'id de la
:user
et:pet
J'ai essayé de couvrir les causes les plus courantes lorsque vous avez besoin d'id de l'élément, et comment les surmonter. J'espère que ce sera utile.
OriginalL'auteur GEkk
Je ne crois pas qu'il existe des solutions de contournement car l'id est en fait générée par la base de données elle-même. L'id ne doit pas être disponibles jusqu'à ce que après que l'objet a été enregistré dans la base de données.
OriginalL'auteur Curtis Edmond
Envisager de faire ce que vous voulez juste après la création de cette instance.
OriginalL'auteur mcmlxxxiii
J'ai juste couru dans une situation similaire lors de la création d'un importateur de données. J'étais à créer un tas de documents de différents types et de les associer avant de l'enregistrer. Lors de l'enregistrement, certains enregistrements ont jeté les erreurs de validation, parce qu'ils avaient validate_presence_of un dossier qui n'était pas encore sauvé.
Si vous utilisez postgresql, active record incréments l'id qu'il attribue à un Modèle en gardant une séquence nommée models_id_seq (sales_id_seq pour la Vente, etc.) dans la base de données. Vous pouvez obtenir le numéro suivant dans cette séquence et de l'incrémenter à la fonction suivante.
Cependant, cette solution n'est pas bonne pratique car il n'y a aucune garantie que l'enregistrement actif gardera id séquences de cette façon à l'avenir. Je ne utiliser ce si elle a été utilisée qu'une seule fois dans mon projet, m'a sauvé beaucoup de travail et il a été bien documenté en termes de pourquoi il ne doit pas être utilisé fréquemment.
OriginalL'auteur the_minted
Je sais que c'est une vieille question, mais pourrait tout aussi bien jeter ma réponse dans le cas où quelqu'un a besoin de faire référence
UserModel
qui peuvent être atténués par des validations
Rails de validations ne fait rien pour atténuer ce risque, seule la base de l'unicité des contraintes aider avec cela (et généralement soulever une exception). Pour expliquer, si l'aller-retour à votre base de données est de 10 ms à tirer/vérifier le dernier id d'utilisateur, et un autre utilisateur est créé à l'intérieur de ce délai, vous disposez de deux valeurs de même. Si c'est un seul site de l'utilisateur, personne ne se soucie, mais rien à distance trafic élevé, c'est un risque que vous devriez éviter. Peut-être regarder postgres séquences ou similaire si vous avez vraiment besoin de ce type de fonctionnalité?
Des conditions de course de côté de l'Utilisateur.dernier ne garantit pas les id les plus élevés, par exemple lorsqu'un
default_scope
aorder(:name)
Des Conditions de course violerait votre login et, partant, le processus de gestion complètement.
OriginalL'auteur theStig