J'essaie de sauvegarder les modifications apportées à ma base de données par le biais d'une tâche rake.
Dans ma tâche de rake, je fais quelque chose comme:
namespace :parts do
desc "Update Parts table, swap names in title"
task :swap => :environment do
Part.swap
end
end
Dans ma classe de partie je fais
def self.swap
Part.all.each do |part|
if (part.title =~ REGEX) == 0
part.title.gsub! REGEX, "2 1"
puts part.title
part.save!
end
end
end
Cependant, cela ne sauve pas la pièce. le save!
retourne vrai. la puts part.title
renvoie la valeur que je veux.
Si j'appelle
Part.update(part.id, title: part.title)
La base de données est mise à jour correctement. Pourquoi est-ce? Est-ce que je fais quelque chose de mal dans ma boucle? Je travaille avec Rails 3.1.3, Rake 0.9.2.2 et MySQL2 0.3.7
Réponses:
17 pour la réponse № 1C’est parce que ActiveRecord détecte que les attributs sont modifiés par l’intermédiaire du setter. Par conséquent, si vous utilisez gsub!
sur un attribut, ActiveRecord ne sait pas qu’il doit mettre à jour la base de données.
Vous devrez probablement faire ceci:
part.title = part.title.gsub REGEX, "2 1"
Mise à jour du commentaire
De plus, si vous essayez d’attribuer un titre à une autre variable, puis à gsub! cela ne fonctionnera pas non plus car c’est le même objet (code de mon projet, noms de variable différents).
ruby-1.9.3-p0 :020 > t = p.name
=> "test"
ruby-1.9.3-p0 :023 > t.object_id
=> 70197586207500
ruby-1.9.3-p0 :024 > p.name.object_id
=> 70197586207500
ruby-1.9.3-p0 :025 > t.gsub! /test/, "not a test"
=> "not a test"
ruby-1.9.3-p0 :037 > p.name = t
=> "not a test"
ruby-1.9.3-p0 :026 > p.save
(37.9ms) BEGIN
** NO CHANGES HERE **
(23.9ms) COMMIT
=> true
Vous devez .dup
la chaîne avant de la modifier.
ruby-1.9.3-p0 :043 > t = p.name.dup
=> "test"
ruby-1.9.3-p0 :044 > t.gsub! /test/, "not a test"
=> "not a test"
ruby-1.9.3-p0 :045 > p.name = t
=> "not a test"
ruby-1.9.3-p0 :046 > p.save
(21.5ms) BEGIN
(20.8ms) UPDATE "projects" SET "name" = "not a test", "updated_at" = "2012-01-02 07:17:22.892032" WHERE "projects"."id" = 108
(21.5ms) COMMIT
=> true