在 Rails 4 中添加引用列迁移
Posted
技术标签:
【中文标题】在 Rails 4 中添加引用列迁移【英文标题】:Add a reference column migration in 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?
【问题讨论】:
【参考方案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
来获取用户实例。以上是关于在 Rails 4 中添加引用列迁移的主要内容,如果未能解决你的问题,请参考以下文章
Rails 5:为啥即使我删除了迁移文件,rails 也会向 schema.rb 添加列