[RUBY] Comment renommer un modèle avec des contraintes de clé externes dans Rails

Si vous souhaitez modifier le nom du modèle, vous n'avez rien à prendre en considération si vous ne modifiez que la table correspondante, mais si vous avez un modèle enfant qui fait référence à la table correspondante, vous devez également modifier la clé externe du modèle enfant. Pour les projets qui n'ont pas encore été publiés, vous pouvez réécrire le fichier de migration existant et faire rails db: migrate: reset, mais pas pour les projets qui ont déjà des données.

Préparation du modèle

Tout d'abord, préparez le modèle. Cette fois, nous préparerons un modèle User et un modèle Task qui sont liés à User has_many Tasks. Pour rendre le contenu du modèle plus facile à comprendre, je n'écrirai pas de colonne autre que la clé externe cette fois.

rails g model User rails g model Task user:references

La commande ci-dessus créera les deux fichiers de migration suivants.

db/migration/20201004121521_create_users.rb



class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|

      t.timestamps
    end
  end
end

db/migration/20201004121556_create_tasks.rb



class CreateTasks < ActiveRecord::Migration[6.0]
  def change
    create_table :tasks do |t|
      t.references :user, null: false, foreign_key: true

      t.timestamps
    end
  end
end

rails db: migrate met à jour schema.rb.

db/schema.rb



ActiveRecord::Schema.define(version: 2020_10_04_121556) do

  create_table "tasks", force: :cascade do |t|
    t.integer "user_id", null: false
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["user_id"], name: "index_tasks_on_user_id"
  end

  create_table "users", force: :cascade do |t|
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  add_foreign_key "tasks", "users"
end

Dans les rails, si vous donnez un type de référence, l'index sera collé sans autorisation. Même si vous ne définissez pas ʻindex: true, t.index [" user_id "], name:" index_tasks_on_user_id "ʻest décrit. De plus, puisque clé_trangère: true a été donné, ʻadd_key_foreign_key" tâches "," utilisateurs "` sont décrits.

Comme mentionné ci-dessus, le modèle utilisateur et le modèle de tâche qui lui est associé ont été créés.

Changer le nom du modèle

Modifions maintenant le modèle User en AdminUser. Commencez par créer un fichier de migration qui modifie normalement le nom du modèle et faites-le migrer.

Créez le fichier suivant avec rails g migration RenameUserToAdminUser et rails db: migrate

db/migration/20201004123215_rename_user_to_admin_user.rb



class RenameUserToAdminUser < ActiveRecord::Migration[6.0]
  def change
    rename_table :users, :admin_users
  end
end

Vérifions schema.rb. Comme vous pouvez le voir, ① l'utilisateur a été renommé en admin_user.

Mais, (2) La clé externe du modèle de tâche reste user_id et n'a pas été renommée. (En parlant bien sûr, bien sûr)

Et (3) La partie contrainte de clé externe est liée à admin_user avec le nom de colonne user_id.

db/schema.rb



ActiveRecord::Schema.define(version: 2020_10_04_123215) do

  create_table "admin_users", force: :cascade do |t| # ←①
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "tasks", force: :cascade do |t|
    t.integer "user_id", null: false # ←②
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["user_id"], name: "index_tasks_on_user_id"
  end

  add_foreign_key "tasks", "admin_users", column: "user_id" # ←③
end

Si vous vérifiez ce schéma, il semble qu'une série de corrections sera effectuée si vous changez le nom de la colonne avec la contrainte de clé externe!

Changer le nom de la colonne de clé externe

Maintenant, créons un fichier de migration qui change le nom de la colonne. rails g migration RenameUserIdToAdminUserId

db/migration/20201004125441_rename_user_id_to_admin_user_id.rb



class RenameUserIdToAdminUserId < ActiveRecord::Migration[6.0]
  def change
    rename_column :tasks, :user_id, :admin_user_id
  end
end

rails db:migrate

Le changement de nom de colonne a été reflété. ④ Le user_id du modèle Task devient admin_user_id, (5) Le nom de colonne de la clé externe n'est plus spécifié.

db/schema.rb



ActiveRecord::Schema.define(version: 2020_10_04_125441) do

  create_table "admin_users", force: :cascade do |t|
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "tasks", force: :cascade do |t|
    t.integer "admin_user_id", null: false # ←④
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["admin_user_id"], name: "index_tasks_on_admin_user_id"
  end

  add_foreign_key "tasks", "admin_users" # ←⑤
end

Résumé

Pour modifier le nom du modèle avec la contrainte de clé externe

  1. Changez le nom du modèle
  2. Modifiez le nom de la clé externe pour le modèle

C'était tout ce que je pouvais faire. C'était étonnamment facile. En particulier, ce sont Rails qui ont changé la direction de la clé externe en changeant simplement le nom du modèle.

Recommended Posts

Comment renommer un modèle avec des contraintes de clé externes dans Rails
[Comment insérer une vidéo dans un hameau avec Rails]
Comment stocker simultanément des données dans un modèle associé à une forme imbriquée (Rails 6.0.0)
[Rails] Comment écrire user_id (clé externe) dans un paramètre fort
Comment insérer une vidéo dans Rails
Comment supprimer des données avec une clé externe
Comment implémenter une fonctionnalité similaire dans Rails
Comment créer facilement un pull-down avec des rails
Comment écrire une recherche de comparaison de dates dans Rails
Comment interroger Array dans jsonb avec Rails + postgres
[Rails 6] Comment définir une image d'arrière-plan dans Rails [CSS]
[Rails] Comment charger JavaScript dans une vue spécifique
Comment gérer les erreurs dans Rails? Impossible de trouver un runtime JavaScript.
[Ruby on Rails] Ajouter une colonne avec des contraintes de clé externe
Comment afficher des graphiques dans Ruby on Rails (LazyHighChart)
Mappage à une classe avec un objet de valeur dans How to My Batis
Comment configurer un proxy avec authentification dans Feign
Comment installer jQuery dans Rails 6
Comment installer Swiper in Rails
Comment créer un fichier jar sans dépendances dans Maven
Comment obtenir la valeur de boolean avec jQuery sous forme simple de rails
Comment implémenter la fonctionnalité de recherche dans Rails
Comment changer le nom de l'application dans les rails
Ajouter une clé externe à la colonne avec migrate
Comment utiliser MySQL dans le didacticiel Rails
[rails] Comment créer un modèle partiel
Comment implémenter la fonctionnalité de classement dans Rails
Comment publier une bibliothèque dans jCenter
Comment utiliser credentials.yml.enc introduit à partir de Rails 5.2
Comment créer un environnement Rails 6 avec Docker
Comment mettre en œuvre un diaporama en utilisant Slick in Rails (un par un et plusieurs par un)
Comment créer une requête à l'aide de variables dans GraphQL [Utilisation de Ruby on Rails]
[Mémo personnel] Comment interagir avec le générateur de nombres aléatoires en Java
Comment mettre à jour les modifications utilisateur dans Rails Devise sans entrer de mot de passe
Comment créer un environnement de développement Ruby on Rails avec Docker (Rails 6.x)
[Rails] Comment obtenir les informations sur l'utilisateur actuellement connecté avec devise
Comment SSH dans Ubuntu à partir d'un terminal avec authentification par clé publique
Comment déboguer le traitement dans le modèle Ruby on Rails avec juste la console
Comment créer un environnement de développement Ruby on Rails avec Docker (Rails 5.x)
[Rails] Comment appliquer le CSS utilisé dans l'application principale avec Administrer
Comment démarrer un conteneur Docker avec un volume monté dans un fichier de commandes
Rails: comment bien écrire une tâche de râteau
Convertir en balise dans la chaîne d'URL avec Rails
[Rails] Comment écrire lors de la création d'une sous-requête
[Rails] rails nouveau pour créer une base de données avec PostgreSQL
[Rails] Comment créer un graphique à l'aide de lazy_high_charts
Comment afficher une page Web en Java
[Rails] Comment utiliser les boîtes de sélection dans Ransack
Comment traduire Rails en japonais en général