Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: Remove foreign key constraint

I have following association with user and semester. And I created user table with semester id as foreign key. So user is not created if semester id not present. But semester id is optional in the registration form.

class User < ApplicationRecord
  belongs_to :semester
end
class Semester < ApplicationRecord
  has_many :users
end
    class CreateUsers < ActiveRecord::Migration[5.1]
      def change
        create_table :users do |t|
          t.string :email
          t.references :semester, foreign_key: true
          t.timestamps
        end
      end
    end

So how can I create another migration to drop the foreign key constraint? So in the user table I there should be two columns email and semester_id but semester_id should not have foreign key constraint because it is an optional field.

like image 964
user1670773 Avatar asked Mar 06 '18 09:03

user1670773


People also ask

How do I rollback a migration in Rails?

To check for status, run rails db:migrate:status . Then you'll have a good view of the migrations you want to remove. Then, run rails db:rollback to revert the changes one by one. After doing so, you can check the status again to be fully confident.

How do I delete a migration in Rails?

【Ruby on Rails】 When you want to delete a migration file you made, you can choose version and delete it. You don't need to execute rails db:rollback many times!

What does Rails db Migrate do?

A Rails migration is a tool for changing an application's database schema. Instead of managing SQL scripts, you define database changes in a domain-specific language (DSL). The code is database-independent, so you can easily move your app to a new platform.


2 Answers

class RemoveSemestersFKFromUsers < ActiveRecord::Migration[5.1]
  def change
    if foreign_key_exists?(:users, :semesters)
      remove_foreign_key :users, :semesters
    end
  end
end

Remember to set the association as optional: true to remove the presence validation as well.

  • ActiveRecord::ConnectionAdapters::SchemaStatements
like image 138
max Avatar answered Oct 03 '22 20:10

max


I experienced this same issue when working on a Rails 6 application.

Here's how I solved it:

I had a Users table and a Roles table. I wanted the Users table to belong to the Roles table, that I wanted to add a reference of the Roles table to the Users table. I also had an Admin and Student Models that inherit from the Users table

Firstly, create a migration to add a reference of the Roles table to the Users table:

rails generate migration AddRoleRefToUsers role:references

This will create a migration file that contains the following:

class AddRoleRefToUsers < ActiveRecord::Migration[6.0]
  def change
    add_reference :users, :role, null: false, foreign_key: true
  end
end

Simply change null: false to null: true. So that we will have;

class AddRoleRefToUsers < ActiveRecord::Migration[6.0]
  def change
    add_reference :users, :role, null: true, foreign_key: true
  end
end

And then migrate the database:

rails db:migrate

Finally, check your user model:

It will contain the following:

class User < ApplicationRecord
  belongs_to :role
end

Simply add optional: true to the belongs_to association. So that we will have:

class User < ApplicationRecord
  belongs_to :role, optional: true
end

That's all.

I hope this helps

like image 37
Promise Preston Avatar answered Oct 03 '22 18:10

Promise Preston