2010-12-22 3 views
59

J'ai ajouté une nouvelle colonne à ma table mais j'ai oublié d'ajouter l'option: default. Maintenant, je veux remplir cette colonne sur chaque ligne.Mettre à jour une colonne, toutes les lignes

Y a-t-il un moyen d'utiliser la console? J'ai cherché google pour l'heure passée mais je ne trouve rien.

Je sais comment le faire pour un seul objet, mais pas pour tous dans un modèle. Foo.find (1) .update_attribute (: MyAttribute, 'valeur')

+0

Voulez-vous attribuer la même valeur à chaque ligne ou à chaque ligne? –

+0

La même valeur pour tous. Merci –

+0

ok, @petrov. Vous pouvez essayer la méthode update_all –

Répondre

116

Essayez ceci:

Foo.update_all(some_column: "bar") 

Cela va générer requête SQL à la base de données:

UPDATE "foos" SET "some_column" = "bar"; 
+0

Merci pake007. Cela marche. Initialement, j'ai essayé ModelName.update mais cela n'a pas fonctionné –

+4

Pas de problème @Petrov, et même plus, vous pouvez passer un paramètre de condition à cette méthode. comme: Foo.update_all ({: new_column => "bar"}, {: old_column_1 => nil}). Il mettra à jour tous les enregistrements qui ont une valeur nulle sur la colonne 'old_column_1'. –

+0

Mais pour les rails 2.2? quelle syntaxe utiliser? – harsh4u

22

Puisque vous avez déjà créé le nouveau champ dans une migration précédente, créer une nouvelle migration:

rails g migration UpdateFoos 

Modi Fais la migration:

def self.up  
    say_with_time "Updating foos..." do 
    Foo.find(:all).each do |f| 
     f.update_attribute :myattribute, 'value' 
    end 
    end 
end 

# from command line 
Rake db:migrate 

Faites-moi savoir si cela fonctionne, il pourrait avoir besoin de quelques ajustements. Voir rails docs pour plus:

+0

Ce serait la bonne approche! – Zabba

+4

Bonne réponse. Rails3 personnes, utilisez Foo.all au lieu de Foo.find (: all) dans l'exemple ci-dessus. – Phantomwhale

+1

Ceci est bon pour les applications hébergeant sur heroku :) – matma

3

vous pouvez faire comme ceci:

Foo.update_all (NEW_COLUMN: "bar")

2

Bien sûr, vous pouvez utiliser smth comme Foo.update_all(:myattribute => "value"), mais il » ll ne modifiera que les données déjà créées. Pour définir la valeur par défaut pour toutes les données "futures" c'est une bonne façon de créer une migration séparée comme ceci:

rails generate migration AddDefaultValueToFoo 

Modifier une nouvelle migration (ex MyAttribute a un type de chaîne.) Comme ceci:

class AddDefaultValueToFoo < ActiveRecord::Migration 
    def self.up 
    change_column :foos, :myattribute, :string, :default => "value" 
    Foo.update_all(:myattribute => "value") 
    end 
end 
Questions connexes