How to rename a model with foreign key constraints in Rails

If you want to change the model name, you don't need to take anything into consideration if you want to change only the corresponding table, but if you have a child model that references the corresponding table, you also need to change the foreign key of the child model. For a project that hasn't been published yet, you can rewrite the existing migration file and do rails db: migrate: reset, but not for a project that already has data.

Model preparation

First, prepare the model. This time, we will prepare the User model and Task model, which are related to User has_many Tasks. To make the contents of the model easier to understand, I will not write any columns other than foreign keys this time.

rails g model User rails g model Task user:references

The above command will create the following two migration files.

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 updates 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

In rails, if you give a reference type, the index will be pasted without permission. Even if you don't set ʻindex: true, t.index ["user_id"], name: "index_tasks_on_user_id" is described. Also, since foreign_key: true was given, ʻadd_foreign_key" tasks "," users " are described.

As mentioned above, the User model and the Task model associated with it have been created.

Change the model name

Now let's change the User model to AdminUser. First, create a migration file that changes the model name normally, and migrate it.

Create the following file with rails g migration RenameUserToAdminUser and 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

Now let's check schema.rb. As you can see, ① user has been renamed to admin_user.

But, (2) The foreign key of the task model remains user_id and has not been renamed. (Speaking of course, of course)

And (3) The foreign key constraint part is linked to admin_user with the column name 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

If you check this schema, it seems that a series of corrections will be completed if you change the column name with the foreign key constraint!

Change the external key column name

Now, let's create a migration file that changes the column name. 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

The column name change has been reflected. ④ The user_id of the Task model becomes admin_user_id, (5) The column name of the foreign key is no longer specified.

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

Summary

To change the model name with a foreign key constraint

  1. Change the model name
  2. Change the foreign key name for the model

This was all I could do. It was unexpectedly easy. In particular, it was Rails that changed the direction of foreign keys just by changing the model name.

Recommended Posts

How to rename a model with foreign key constraints in Rails
[How to insert a video in haml with Rails]
How to store data simultaneously in a model associated with a nested form (Rails 6.0.0)
How to use a foreign key with FactoryBot ~ Another solution
[Rails] How to write user_id (foreign key) in strong parameter
How to insert a video in Rails
How to delete data with foreign key
How to implement a like feature in Rails
How to easily create a pull-down in Rails
How to make a follow function in Rails
[Rails] How to log in with a name by adding a devise name column
How to make a factory with a model with polymorphic association
How to write a date comparison search in Rails
How to query Array in jsonb with Rails + postgres
[Rails 6] How to set a background image in Rails [CSS]
[Rails] How to load JavaScript in a specific view
How to get started with creating a Rails app
How to deal with errors in Rails s could not find a JavaScript runtime.
[Ruby on Rails] Add a column with a foreign key constraint
How to display a graph in Ruby on Rails (LazyHighChart)
Mapping to a class with a value object in How to MyBatis
How to set up a proxy with authentication in Feign
[Rails] How to write in Japanese
How to introduce jQuery in Rails 6
How to get along with Rails
How to install Swiper in Rails
How to make a jar file with no dependencies in Maven
How to run a job with docker login in AWS batch
How to get boolean value with jQuery in rails simple form
How to encrypt and decrypt with RSA public key in Java
How to implement search functionality in Rails
How to change app name in rails
Add foreign key to column with migrate
[Rails] How to use rails console with docker
How to use MySQL in Rails tutorial
Steps to set a favicon in Rails
[rails] How to create a partial template
How to implement ranking functionality in Rails
How to publish a library in jCenter
How to use credentials.yml.enc introduced in Rails 5.2
How to build Rails 6 environment with Docker
How to implement a slideshow using slick in Rails (one by one & multiple by one)
How to create a query using variables in GraphQL [Using Ruby on Rails]
[Personal memo] How to interact with a random number generator in Java
How to update user edits in Rails Devise without entering a password
How to build a Ruby on Rails development environment with Docker (Rails 6.x)
[Rails] How to get the user information currently logged in with devise
How to SSH into Ubuntu from a terminal with public key authentication
How to debug the processing in the Ruby on Rails model only on the console
How to display the text entered in text_area in Rails with line breaks
How to build a Ruby on Rails development environment with Docker (Rails 5.x)
[Rails] How to apply the CSS used in the main app with Administrate
How to start a Docker container with a volume mounted in a batch file
Rails: How to write a rake task nicely
Convert to a tag to URL string in Rails
[Rails] How to write when making a subquery
[Rails] rails new to create a database with PostgreSQL
[Rails] How to create a graph using lazy_high_charts
How to display a web page in Java
[Rails] How to use select boxes in Ransack
How to translate Rails into Japanese in general