/ / rake / rails .save! pas de mise à jour de la base de données - ruby-on-rails, rake

rake / rails .save! ne pas mettre à jour la base de données - ruby-on-rails, rake

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 № 1

C’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