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.
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.
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!
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
Pour modifier le nom du modèle avec la contrainte de clé externe
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.