【问题标题】:Rails: Remove foreign key constraintRails:删除外键约束
【发布时间】:2018-03-06 09:18:56
【问题描述】:

我与用户和学期有以下关联。我创建了以学期 ID 作为外键的用户表。因此,如果学期 ID 不存在,则不会创建用户。但学期 ID 在注册表中是可选的。

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

那么如何创建另一个迁移来删除外键约束?因此,在用户表中,我应该有两列电子邮件和学期 ID,但学期 ID 不应该有外键约束,因为它是一个可选字段。

【问题讨论】:

    标签: ruby-on-rails rails-migrations


    【解决方案1】:
    class RemoveSemestersFKFromUsers < ActiveRecord::Migration[5.1]
      def change
        if foreign_key_exists?(:users, :semesters)
          remove_foreign_key :users, :semesters
        end
      end
    end
    

    请记住将关联设置为optional: true 以删除存在验证。

    【讨论】:

    • 如果列也不能为空,您可能需要执行change_column :users, :semester_id, :integer, null: true
    • 回滚这个迁移怎么样?它不会创建foreign_key
    • ...它不会因为'foreign_key_exists'而创建foreign_key?条件..没有这个条件它工作正常
    【解决方案2】:

    我在使用 Rails 6 应用程序时遇到了同样的问题。

    我是这样解决的

    我有一个Users 表和一个Roles 表。我希望Users 表属于Roles 表,我想将Roles 表的引用添加到Users 表。我还有一个继承自 Users 表的 AdminStudent 模型

    首先,创建一个迁移,将Roles 表的引用添加到Users 表:

    rails generate migration AddRoleRefToUsers role:references
    

    这将创建一个包含以下内容的迁移文件:

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

    只需将null: false 更改为null: true。这样我们就有了;

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

    然后迁移数据库:

    rails db:migrate
    

    最后,检查您的user 模型:

    它将包含以下内容:

    class User < ApplicationRecord
      belongs_to :role
    end
    

    只需将optional: true 添加到belongs_to 关联。这样我们就有了:

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

    就是这样。

    我希望这会有所帮助

    【讨论】:

      【解决方案3】:

      在您的模型中使参考成为可选:

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

      See here, 4.1.2.11

      【讨论】:

      • 这不是一个好主意,因为在大多数数据库中外键不可为空。这只是删除了应用程序级别的验证。
      • 你有什么建议?
      • remove_foreign_key 显然。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-24
      • 2018-11-28
      • 2015-06-11
      • 1970-01-01
      相关资源
      最近更新 更多