引用的 add_column (Rails)

Posted

技术标签:

【中文标题】引用的 add_column (Rails)【英文标题】:add_column for references (Rails) 【发布时间】:2010-10-04 08:57:51 【问题描述】:

我有以下完美运行的 Rails 迁移(删除了不相关的部分):

create_table :comments do |t|
  t.text :body
  t.references :post
end

现在我想在我的comments 表中添加一个author 列(这是用户的用户标识),但我不知道该怎么做(我很想只写 mysql - 使用execute 的特定语法)。

我一直在查看 add_column here,它没有提到 references。我实际上找到了TableDefinition#references,但我不知道如何将它与add_column 语句一起使用。

这可能吗?另外,对于MySql,“引用”功能是否真的没有建立表之间的关系?

【问题讨论】:

【参考方案1】:

虽然现在想从中获得任何积分都为时已晚,但我想我会为后代发布最好的方法:)

使用 change_table 而不是 create_table 将列添加到已经存在的表中,并具有所有 TableDefinition 优点:

self.up do
  change_table :comments do |t|
    t.references :author
  end
end

这可能看起来微不足道,但像 Devise 这样的其他 gem 大量使用自己的自定义表定义,这样您仍然可以使用它们。

【讨论】:

好的,所以我将作者字段添加到 cmets 表并使用引用。这对 MySql 有影响吗?我还需要更换型号吗? 是的,您仍然需要在您的 author.rb 中添加“has_many :cmets”,并在您的 comment.rb 中添加“belongs_to :author”。迁移代码仅在数据库中创建字段,在您调用我在此处列出的正确 ActiveRecord 方法之前,这些字段是无用的。 @Jamie Bellmyer 进行反向迁移的最佳方法是什么?我喜欢让我的迁移保持双向清洁。 @Jackson Miller 没有 t.unreference 来撤消您的引用添加,但您可以在上面的示例中使用 t.remove :author_id 的长方法。如果您使用了“t.references :author, :polymorphic => true”,那么您还需要在向下迁移中使用“t.remove author_type”。 不幸的是,这个答案是 4-5 岁。尽管这可以工作,但这不再是 Rails 4+ 可接受的方法。请参阅 Rajeev Kannav Sharma 和 Josh Crozier 的 DRY 单线建议【参考方案2】:
add_reference :table_name, :reference, index: true

【讨论】:

这是一个很好的答案,对于 Rails 4 来说更少。这里API reference 同意。这现在应该是 Rails 4+ 的“新”正确答案。 你也可以通过add_reference :table_name, :reference, polymorphic: true, index: true 为了我的生意,我是add_reference :users, :tenant, foreign_key: true【参考方案3】:

终于明白了

add_column :locations, :state_id , :integer, :references => "states"

【讨论】:

Chickoklkar,太好了。如果您可以请删除您的其他答案,并且如果您可以链接到 Rails 文档,那就太好了。谢谢! 这真的有什么特别的吗?我找不到任何说明 add_column 实际上会使用选项中的 :references 符号执行任何操作的文档。 这在 2012 年可能是正确的答案,但在 Rails 4 中它是 @rajeev-kannav-sharma 的答案。【参考方案4】:

首先,做:

script/generate migration AddAuthorIdToComments

打开生成的文件并添加这一行:

add_column :comments, :author_id, :integer

然后在你的模型文件中:

class User < ActiveRecord::Base
  has_many :comments, :foreign_key => "author_id"
end

class Comment
  belongs_to :author, :class_name => User
end

【讨论】:

非常好,谢谢。当然,将列添加为整数并不是我所希望的,但因为这就是原始迁移所做的……感谢您概述了如何在模型类中设置关系。 简单的事实是,您不能在这种情况下使用引用,因为它只能用于表定义。是的,正如 Craig 所说,迁移并不关心在数据库中设置外键。 好的,我明白了:表定义:在列级别它不可用(仅在表级别)。一个问题:如果 User 中的列称为“id”,它可以工作,对吗? “author_id”只是 cmets 中新列的名称,对吧? 是的,这两者之间的连接是在模型级别定义的(参见foreign_key,class_name)。 “class_name => 用户”是做什么的?【参考方案5】:

我已经有一段时间没有看到这个了,但最后我检查了迁移不支持创建外键。不过,幸运的是,there is a plug-in for it。我用过这个,效果很好。

【讨论】:

【参考方案6】:

您可以在新的迁移中添加 add_column(:table, :column_name, :type, :options) 列。

【讨论】:

谢谢迈克。 :type 和 :options 是什么?

以上是关于引用的 add_column (Rails)的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL:在 Rails 迁移中使用 add_column "after" 选项

rails add_column 具有默认值但默认值不生效

Rails 迁移:检查存在并继续?

在 Rails 中关闭 json 键引用

在 Rails 5 中添加引用列迁移

Rails 使用同一命名空间中的模型作为 belongs_to 引用,如何从外部引用模型