user1670773
user1670773

Reputation: 1037

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.

Upvotes: 16

Views: 19835

Answers (3)

Promise Preston
Promise Preston

Reputation: 29078

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

Upvotes: 0

max
max

Reputation: 102343

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.

Upvotes: 20

Ben
Ben

Reputation: 5192

Make the reference optional in your model :

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

See here, 4.1.2.11

Upvotes: -1

Related Questions