ChatGPT解决这个技术问题 Extra ChatGPT

Rails 3 迁移:添加参考列?

如果我使用(例如)创建一个新的 rails 3 迁移

rails g migration tester title:tester user:references

,一切正常......但是,如果我添加一个包含以下内容的列:

rails g migration add_user_to_tester user:references

无法识别参考字段。简而言之,问题是:如何从命令行向 rails 迁移添加引用列?


e
e382df99a7950919789725ceeec126

如果您使用的是 Rails 4.x,您现在可以生成带有引用的迁移,如下所示:

rails generate migration AddUserRefToProducts user:references

就像您在 rails guides 上看到的那样


例如,参见 edgeguides.rubyonrails.org/active_record_migrations.html 中的第 2.1 节。
如何为外键指定列名而不是自动生成的名称?
@j您是否可以使用多态:user:references{polymorphic}。
@PauloFidalgo 你能解释一下如何做到这一点吗?可能是一些链接指南? (谈论多态)
d
dan-klasson

编辑:这是一个过时的答案,不应该应用于 Rails 4.x+

当您可以将整数 id 用于引用的类时,您不需要添加引用。

我想说使用引用而不是普通整数的优点是模型将使用 belongs_to 进行预定义,并且由于模型已经创建并且在迁移现有内容时不会受到影响,因此目的有点丢失。

所以我会这样做:

rails g migration add_user_id_to_tester user_id:integer

然后在Tester模型中手动添加belongs_to :user


但这不会在支持它的数据库上创建适当的外键约束,对吧?
不,afaik Rails 永远不会在数据库上创建外键限制,除非您添加插件来为您执行此操作。
只是在研究这篇文章,请问我到底如何添加参考
记得用 user:integer:index 添加索引
答案已过时,请参阅@Paulo 对现代导轨的回答。
I
Itay Grudev

请注意,您很可能也需要该列的索引。

class AddUserReferenceToTester < ActiveRecord::Migration
  def change
    add_column :testers, :user_id, :integer
    add_index  :testers, :user_id
  end
end

为什么?对于大多数 belongs_to 关系来说,这是真的吗?
这确实是出于性能原因,如果您在该 belongs_to 关系的另一侧有一个 has_many/has_one ,它会派上用场。如果您绝对确定不会通过 user.testers,则可以省略索引。
rails g migration ... 生成了 add_reference :installs, :device, index: true,它也创建了索引。
M
Martin Cabrera Diaubalick

通过上述两个步骤,您仍然缺少外键约束。这应该有效:

  class AddUserReferenceToTester < ActiveRecord::Migration
      def change
          add_column :testers, :user_id, :integer, references: :users
      end
  end

这是这里唯一的实际答案。外键是这里最关键的部分
这应该被标记为正确答案,因为问题要求 rails 3
g
gl03

您可以在更改迁移中使用引用。这是有效的 Rails 3.2.13 代码:

class AddUserToTester < ActiveRecord::Migration
  def change
    change_table :testers do |t|
      t.references :user, index: true 
    end
  end
  def down
    change_table :testers do |t|
      t.remove :user_id
    end
  end
end

参照:http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/change_table


变化和下降方法?不是 up 和 down 方法吗?
@MaicolBen 是的,您也可以不使用 down 方法。
@MaicolBen 如果没有 down 方法,我在使用 Rails 3.2 回滚时得到了 ActiveRecord::IrreversibleMigration。我还必须将 change 更改为 up
I
Itay Grudev

运行 rails g migration AddUserRefToSponsors user:references 将生成以下迁移:

def change
  add_reference :sponsors, :user, index: true
end

这适用于哪个版本的 Rails?
Z
Zamith

添加列时,您需要将该列设为整数,并尽可能坚持使用 rails 约定。因此,对于您的情况,我假设您已经有一个 Tester 和 User 模型,以及 testers 和 users 表。

要添加外键,您需要创建一个名为 user_id 的整数列(约定):

add_column :tester, :user_id, :integer

然后在 tester 模型中添加一个 belongs_to:

class Tester < ActiveRecord::Base
  belongs_to :user
end

而且您可能还想为外键添加索引(这是参考已经为您做的事情):

add_index :tester, :user_id

m
masterweily

这样就可以了:

rails g migration add_user_to_tester user_id:integer:index

我喜欢这也添加了您最可能想要的索引。
N
Neha

您可以通过以下方式通过命令行添加对模型的引用:

rails g migration add_column_to_tester user_id:integer

这将生成一个迁移文件,如:

class AddColumnToTesters < ActiveRecord::Migration
  def change
    add_column :testers, :user_id, :integer
  end
end

每次我使用它都可以正常工作..


s
shilovk

对于 Rails 4

生成器接受列类型作为参考(也可用作 belongs_to)。

此迁移将创建一个 user_id 列和适当的索引:

$ rails g migration AddUserRefToProducts user:references 

生成:

class AddUserRefToProducts < ActiveRecord::Migration
  def change
    add_reference :products, :user, index: true
  end
end

http://guides.rubyonrails.org/active_record_migrations.html#creating-a-standalone-migration

对于 Rails 3

助手称为引用(也可用作 belongs_to)。

此迁移将创建相应类型的 category_id 列。请注意,您传递的是模型名称,而不是列名称。 Active Record 会为您添加 _id

change_table :products do |t|
  t.references :category
end

如果您有多态 belongs_to 关联,则引用将添加所需的两列:

change_table :products do |t|
  t.references :attachment, :polymorphic => {:default => 'Photo'}
end

将添加一个 attachment_id 列和一个默认值为 Photo 的字符串 attachment_type 列。

http://guides.rubyonrails.org/v3.2.21/migrations.html#creating-a-standalone-migration