【问题标题】:Add a reference column migration in Rails 4在 Rails 4 中添加引用列迁移
【发布时间】:2014-05-13 22:42:34
【问题描述】:

一个用户有很多上传。我想在引用user 的uploads 表中添加一列。迁移应该是什么样子?

这就是我所拥有的。我不确定是否应该使用 (1) :user_id, :int 或 (2) :user, :references。我什至不确定(2)是否有效。只是想以“rails”的方式做到这一点。

class AddUserToUploads < ActiveRecord::Migration
  def change
    add_column :uploads, :user_id, :integer
  end
end

Rails 3 以外的相关问题。Rails 3 migrations: Adding reference column?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 foreign-keys rails-activerecord rails-migrations


    【解决方案1】:

    只是为了记录是否有人有同样的问题......

    在我的情况下,我一直在使用 :uuid 字段,而上述答案不适用于我的情况,因为 rails 5 正在使用 :bigint 而不是 :uuid 创建列:

    add_reference :uploads, :user, index: true, type: :uuid
    

    参考:Active Record Postgresql UUID

    【讨论】:

    • 发生了什么也更清楚了。但是,是的,UUID 现在应该是标准的了。
    【解决方案2】:

    创建迁移文件

    rails generate migration add_references_to_uploads user:references
    

    默认外键名

    这将在上传表中创建一个 user_id 列作为外键

    class AddReferencesToUploads < ActiveRecord::Migration[5.2]
      def change
        add_reference :uploads, :user, foreign_key: true
      end
    end
    

    用户模型:

    class User < ApplicationRecord
      has_many :uploads
    end
    

    上传模型:

    class Upload < ApplicationRecord
      belongs_to :user
    end
    

    自定义外键名:

    add_reference :uploads, :author, references: :user, foreign_key: true
    

    这将在上传表中创建一个 author_id 列作为外键。

    用户模型:

    class User < ApplicationRecord
      has_many :uploads, foreign_key: 'author_id'
    end
    

    上传模型:

    class Upload < ApplicationRecord
      belongs_to :user
    end
    

    【讨论】:

    • 如何指定一个字段用作外键?假设我想使用唯一的字符串字段而不是行 ID 作为外键。迁移语法如何?
    • 如果我理解正确,您想使用行 ID 以外的字段。 add_foreign_key :from_table, :to_table, column: :field primary_key: "row_id" 出于性能原因,您可能还想对其进行索引
    【解决方案3】:

    如果您喜欢 up 和 down 方法的另一种替代方法,请尝试以下方法:

      def up
        change_table :uploads do |t|
          t.references :user, index: true
        end
      end
    
      def down
        change_table :uploads do |t|
          t.remove_references :user, index: true
        end
      end
    

    【讨论】:

      【解决方案4】:

      [使用 Rails 5]

      生成迁移:

      rails generate migration add_user_reference_to_uploads user:references
      

      这将创建迁移文件:

      class AddUserReferenceToUploads < ActiveRecord::Migration[5.1]
        def change
          add_reference :uploads, :user, foreign_key: true
        end
      end
      

      现在,如果您观察架构文件,您将看到上传表包含一个新字段。类似:t.bigint "user_id" 或 t.integer "user_id"。

      迁移数据库:

      rails db:migrate
      

      【讨论】:

      • 这个答案似乎与@Mirror318 的答案重复。如果您认为其中缺少某些内容,请对上述答案发表评论。谢谢。
      【解决方案5】:

      做同样事情的另一种语法是:

      rails g migration AddUserToUpload user:belongs_to
      

      【讨论】:

        【解决方案6】:

        Rails 4.x

        当您已有 users 和 uploads 表并希望在它们之间添加新关系。

        您需要做的就是:使用以下命令生成迁移:

        rails g migration AddUserToUploads user:references
        

        这将创建一个迁移文件:

        class AddUserToUploads < ActiveRecord::Migration
          def change
            add_reference :uploads, :user, index: true
          end
        end
        

        然后,使用 rake db:migrate 运行迁移。 此迁移将负责将名为 user_id 的新列添加到 uploads 表(引用 users 表中的 id 列),此外它还将在新列上添加索引。

        更新 [适用于 Rails 4.2]

        不能信任 Rails 来保持引用完整性; 关系数据库在这里为我们提供了帮助。这意味着我们可以在数据库级别本身添加外键约束,并确保数据库将拒绝任何违反此集合引用完整性的操作。正如@infoget 评论的那样,Rails 4.2 提供了对外键(参照完整性) 的原生支持。这不是必需的,但您可能希望将外键(因为它非常有用)添加到我们在上面创建的引用中。

        要将外键添加到现有引用,请创建一个新迁移以添加外键:

        class AddForeignKeyToUploads < ActiveRecord::Migration
          def change
            add_foreign_key :uploads, :users
          end
        end
        

        要创建一个完全带有外键的全新引用(在 Rails 4.2 中),请使用以下命令生成迁移:

        rails g migration AddUserToUploads user:references
        

        这将创建一个迁移文件:

        class AddUserToUploads < ActiveRecord::Migration
          def change
            add_reference :uploads, :user, index: true
            add_foreign_key :uploads, :users
          end
        end
        

        这将为uploads 表的user_id 列添加一个新的外键。键引用users 表中的id 列。

        注意:这是除了添加引用之外,因此您仍然需要先创建引用,然后创建外键(您可以选择创建外键键入相同的迁移或单独的迁移文件)。 Active Record 仅支持单列外键,目前仅支持 mysql、mysql2 和 PostgreSQL 适配器。不要尝试与sqlite3 等其他适配器一起使用。请参阅Rails Guides: Foreign Keys 以供参考。

        【讨论】:

        • 在许多情况下,添加外键也很好。 add_foreign_key (Rails 4.2)
        • 我相信您可以在一行中完成所有操作:add_reference :uploads, :user, index: true, foreign_key: true @KirtiThorat
        • 现在,如果您使用特殊的生成器语法进行迁移,Rails 4.2 将自动创建包含外键约束的正确迁移。 rails g migration AddUserToUploads user:references 在适当的迁移中产生 add_reference :uploads, :user, index: true, foreign_key: true。
        • 使用...index: true, foreign_key: true 代替行add_foreign_key。
        • 为什么我们需要foreign_key 和t.reference? t.reference本质上不等于foriegn_key + index吗?
        【解决方案7】:

        导轨 5

        您仍然可以使用此命令来创建迁移:

        rails g migration AddUserToUploads user:references
        

        迁移看起来与以前有些不同,但仍然有效:

        class AddUserToUploads < ActiveRecord::Migration[5.0]
          def change
            add_reference :uploads, :user, foreign_key: true
          end
        end
        

        注意是:user,而不是:user_id

        【讨论】:

        • 对于命名空间类,例如 Local::User 而不是 User 执行类似 rails g migration AddLocalUserToUploads user:references 的操作。
        • 这会自动添加:index
        • @Zeke 是的,运行迁移并检查您的架构,它应该说类似于t.index ["user_id"], name: "index_uploads_on_user_id", using: :btree
        • 是的,当我在迁移中手动添加 add_index 时出现“索引存在”错误:P @Mirror318
        • 我们还应该在Upload类中添加belongs_to :user,这样我们就可以使用upload.user来获取用户实例。
        猜你喜欢
        • 2017-02-17
        • 1970-01-01
        • 1970-01-01
        • 2020-05-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-16
        相关资源
        最近更新 更多