用户上传次数过多。我想在上传表中添加一个引用用户的列。迁移应该是什么样的?

这是我有的。我不确定我是否应该使用(1):user_id,:int或(2):user,:引用。我甚至不确定(2)是否有效。我只是想按"铁轨"的方式来。

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

除了Rails 3之外的相关问题。Rails 3迁移:添加参考列?


Rails 4.倍

当您已经有用户并上传表,并希望在它们之间添加新的关系时。

你所需要做的就是:使用下面的命令生成一个迁移:

rails g migration AddUserToUploads user:references

这将创建一个迁移文件:

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

然后,使用rake db:migrate运行迁移。 这个迁移会注意到在uploads表中添加一个名为user_id的新列(引用users表中的id列),另外它还会在新列上添加一个索引。

更新[针对Rails 4.2]

Rails can’t be trusted to maintain referential integrity; relational databases come to our rescue here. What that means is that we can add foreign key constraints at the database level itself and ensure that database would reject any operation that violates this set referential integrity. As @infoget commented, Rails 4.2 ships with native support for foreign keys(referential integrity). It's not required but you might want to add foreign key(as it's very useful) to the reference that we created above.

要向现有引用添加外键,请创建一个新的迁移来添加外键:

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列添加一个新的外键。键引用用户表中的id列。

注意:这是添加引用之外的操作,因此您仍然需要先创建引用,然后再创建外键(您可以选择在同一个迁移或单独的迁移文件中创建外键)。活动记录只支持单列外键,目前只支持mysql, mysql2和PostgreSQL适配器。不要在sqlite3等其他适配器上尝试这种方法。参考Rails指南:外键。

Rails 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

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

rails g migration AddUserToUpload user:belongs_to

[使用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

现在,如果观察模式文件,您将看到uploads表包含一个新字段。比如:t.bigint "user_id"或t.integer "user_id"。

迁移数据库:

rails db:migrate

如果你喜欢另一种向上和向下的方法,试试这个:

  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

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

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

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

参考:Active Record Postgresql UUID

创建一个迁移文件

rails generate migration add_references_to_uploads user:references

默认外键名称

这将在uploads表中创建一个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
class MigrationName < ActiveRecord::Migration[7.0]
  disable_ddl_transaction!
  
  def change
    add_reference :uploads, :user, index: {algorithm: :concurrently}
  end
end