Existe-t-il un moyen de remplacer la valeur d'identifiant d'un modèle lors de la création? Quelque chose comme:
Post.create(:id => 10, :title => 'Test')
serait idéal, mais ne fonctionnera évidemment pas.
ruby-on-rails
activerecord
Codebeef
la source
la source
Réponses:
id est juste attr_protected, c'est pourquoi vous ne pouvez pas utiliser l'affectation en masse pour le définir. Cependant, lors du réglage manuel, cela fonctionne simplement:
Je ne sais pas quelle était la motivation d'origine, mais je le fais lors de la conversion de modèles ActiveHash en ActiveRecord. ActiveHash vous permet d'utiliser la même sémantique appartient_to dans ActiveRecord, mais au lieu d'avoir une migration et de créer une table, et d'encourir la surcharge de la base de données à chaque appel, vous stockez simplement vos données dans des fichiers yml. Les clés étrangères de la base de données référencent les identifiants en mémoire dans le fichier yml.
ActiveHash est idéal pour les listes de sélection et les petites tables qui changent rarement et ne changent que par les développeurs. Ainsi, lorsque vous passez d'ActiveHash à ActiveRecord, il est plus simple de garder toutes les références de clé étrangère identiques.
la source
ActiveRecord::VERSION::STRING == "3.2.11"
ici (avec l'adaptateur sqlite3) et ce qui précède fonctionne pour moi.Essayer
cela devrait vous donner ce que vous recherchez.
la source
Vous pouvez également utiliser quelque chose comme ceci:
Bien que comme indiqué dans la documentation , cela contournera la sécurité des affectations de masse.
la source
Pour les rails 4:
Other Rails 4 réponses n'a pas fonctionné pour moi. Beaucoup d'entre eux semblaient changer lors de la vérification à l'aide de la console Rails, mais lorsque j'ai vérifié les valeurs dans la base de données MySQL, elles sont restées inchangées. D'autres réponses ne fonctionnaient que parfois.
Pour MySQL au moins, attribuer un
id
numéro d'identification à incrémentation automatique ne fonctionne pas sauf si vous utilisezupdate_column
. Par exemple,Si vous changez
create
pour utilisernew
+,save
vous aurez toujours ce problème. Changer manuellement les élémentsid
similairesp.id = 10
produit également ce problème.En général, j'utiliserais
update_column
pour changer leid
même si cela coûte une requête de base de données supplémentaire car cela fonctionnera tout le temps. Il s'agit d'une erreur qui peut ne pas apparaître dans votre environnement de développement, mais qui peut discrètement corrompre votre base de données de production tout en indiquant qu'elle fonctionne.la source
Post.new.update(id: 10, title: 'Test')
En fait, il s'avère que faire les travaux suivants:
la source
validate: false
, au lieu de simplementfalse
. Cependant, vous rencontrez toujours le problème des attributs protégés - il existe un moyen distinct de contourner ce que j'ai décrit dans ma réponse.Comme Jeff le souligne, id se comporte comme s'il était attr_protected. Pour éviter cela, vous devez remplacer la liste des attributs protégés par défaut. Faites attention en faisant cela partout où les informations d'attribut peuvent provenir de l'extérieur. Le champ id est protégé par défaut pour une raison.
(Testé avec ActiveRecord 2.3.5)
la source
nous pouvons remplacer attributes_protected_by_default
la source
Cela ne me semble pas être le genre de chose que vous voudriez normalement faire, mais cela fonctionne très bien si vous devez remplir une table avec un ensemble fixe d'identifiants (par exemple lors de la création de valeurs par défaut à l'aide d'une tâche de râteau) et vous souhaitez remplacer l'incrémentation automatique (afin que chaque fois que vous exécutez la tâche, la table soit remplie avec les mêmes identifiants):
la source
Placez cette fonction create_with_id en haut de votre seeds.rb, puis utilisez-la pour créer votre objet là où des identifiants explicites sont souhaités.
et utilisez-le comme ça
à la place d'utiliser
Foo.create({id:1,name:"My Foo",prop:"My other property"})
la source
Ce cas est un problème similaire qui était nécessaire de remplacer le
id
avec une sorte de date personnalisée:Puis :
Les rappels fonctionnent très bien.
Bonne chance!.
la source
id
horodatage basé sur Unix. J'ai fait ça à l'intérieurbefore_create
. Fonctionne très bien.Pour Rails 3, le moyen le plus simple de le faire est d'utiliser
new
avec lewithout_protection
raffinement, puissave
:Pour les données de départ, il peut être judicieux de contourner la validation, ce que vous pouvez faire comme ceci:
Nous avons en fait ajouté une méthode d'assistance à ActiveRecord :: Base qui est déclarée immédiatement avant l'exécution des fichiers de départ:
Et maintenant:
Pour Rails 4, vous devriez utiliser StrongParams au lieu d'attributs protégés. Si tel est le cas, vous pourrez simplement attribuer et enregistrer sans passer aucun drapeau à
new
:la source
{}
la réponse de Samuel ci-dessus (Rails3).id
a toujours 10 ans.id
été passé à 10 - c'est donc exactement ce qu'il devrait être. Si ce n'est pas ce à quoi vous vous attendiez, pouvez-vous clarifier avec un exemple?Dans Rails 4.2.1 avec Postgresql 9.5.3,
Post.create(:id => 10, :title => 'Test')
fonctionne tant qu'il n'y a pas déjà une ligne avec id = 10.la source
vous pouvez insérer l'identifiant par sql:
la source