web-dev-qa-db-fra.com

Rails 4: Supprimer la contrainte non nulle de la colonne de table avec la migration?

Étant donné les schema.rb:

  create_table "people", force: true do |t|
    t.string   "name",  null: false
    t.integer  "age"
    t.integer  "height"
    t.string   "email"
    t.boolean  "married",  default: false
    t.text     "bio"
    t.integer  "fav_number"
    t.decimal  "lucky_num",  precision: 2, scale: 2
    t.datetime "birthday"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

Je voudrais supprimer la valeur par défaut de name de null: false. J'ai essayé d'exécuter une migration distincte avec change_column_default, mais cela n'a eu aucun impact sur schema.rb. Aucune suggestion?

42
gabethegrape

De la docs :

  def up
    change_column_default :table_name, :status, 0
  end

  def down
    change_column_default :table_name, :status, nil
  end
70
luigi7up

La fonction 'up' fera certainement l'affaire lorsque vous effectuez db: migrate.
Mais à l'avenir, dans certains cas, comme la restauration, vous souhaiterez peut-être une fonction pour inverser cette migration particulière.

def up
  change_column_null :people, :name, true
end

def down
  change_column_null :people, :name, false
end
14
Ran Galili

Il semble que vous n'essayiez pas de modifier la valeur par défaut de la colonne, mais plutôt de supprimer la contrainte NOT NULL et d'autoriser les valeurs nulles (c'est-à-dire passer de "null: false" à la valeur par défaut "null: true"). Si tel est le cas, vous pouvez utiliser change_column_null :

class ChangeNameNull < ActiveRecord::Migration
  def change
    change_column_null :people, :name, true
  end
end

Edit 1: - Correction d'une faute de frappe

8
ddebruler
def change
  change_column_null(:users, :admin, false, <put a default value here> )
  # change_column(:users, :admin, :string, :default => "")
end

La modification d'une colonne contenant des valeurs NULL pour ne pas autoriser NULL entraînera des problèmes. C'est exactement le type de code qui fonctionnera correctement dans votre configuration de développement, puis se bloquera lorsque vous essayez de le déployer sur votre [~ # ~] live [~ # ~] production. Vous devez d'abord changer les valeurs NULL en quelque chose de valide et puis interdire les valeurs NULL. La 4ème valeur dans change_column_null fait exactement cela. Voir documentation pour plus de détails.

De plus, je préfère généralement définir une valeur par défaut pour le champ, donc je n'aurai pas besoin de spécifier la valeur du champ chaque fois que je crée un nouvel objet. J'ai également inclus le code commenté pour le faire.

3
Rick Smith