ChatGPT解决这个技术问题 Extra ChatGPT

在 Rails 中使用 user_id:integer 与 user:references 生成模型

我对如何生成一个属于另一个模型的模型感到困惑。我的书使用这种语法将 Micropost 与用户相关联:

rails generate model Micropost user_id:integer

https://guides.rubyonrails.org/active_record_migrations.html#creating-a-standalone-migration 说要这样做:

rails generate model Micropost user:references

这两个产生的迁移是不同的。另外,对于前者,rails 是如何知道 user_id 是引用 user 的外键?谢谢!


G
Gautam Chibde

运行迁移时,两者都将生成相同的列。在 rails 控制台中,您可以看到是这样的:

:001 > Micropost
=> Micropost(id: integer, user_id: integer, created_at: datetime, updated_at: datetime)

第二个命令在您的 Micropost 模型中添加 belongs_to :user 关系,而第一个命令没有。指定此关系后,ActiveRecord 将假定外键保存在 user_id 列中,并将使用名为 User 的模型来实例化特定用户。

第二个命令还在新的 user_id 列上添加索引。


是否可以使用两个表的引用生成模型
请注意,它不会在其他模型(用户)上添加 has_many 关联,您可能也想添加它。
我认为使用 :references 会在外键上创建索引,而手动创建列不会?
G
Gautam Chibde

rails 如何知道 user_id 是引用用户的外键?

Rails 本身不知道 user_id 是引用 user 的外键。在第一个命令 rails generate model Micropost user_id:integer 中,它只添加了一个列 user_id,但是 rails 不知道 col 的使用。您需要手动将线放入 Micropost 模型中

class Micropost < ActiveRecord::Base
  belongs_to :user
end

class User < ActiveRecord::Base
  has_many :microposts
end

关键字 belongs_tohas_many 确定这些模型之间的关系并将 user_id 声明为 User 模型的外键。

后面的命令 rails generate model Micropost user:referencesMicropost 模型中添加行 belongs_to :user 并在此声明为外键。

https://i.stack.imgur.com/y6J0P.png

但是,如果您使用后一种方法,您会发现迁移文件如下所示:

def change
    create_table :microposts do |t|
      t.references :user, index: true

      t.timestamps null: false
    end
    add_foreign_key :microposts, :users

https://i.stack.imgur.com/ew9UO.png


似乎最新的 Rails 生成器用 t.references 行的选项 foreign_key: true 替换了 add_foreign_key 操作,这意味着 index: true。所以现在是t.references :user, foreign_key: true。目前没有可用的 foreign_key 选项的文档,所以这只是我的假设。
哦,add_reference action 有一个 :foreign_key 选项,它添加适当的外键约束。我猜这个选项在创建表时会做同样的事情。
你如何将你的 ruby 数据库导出到工作台?你能在这里回答这个问题吗:stackoverflow.com/questions/42982921/…
add_foreign_key :microposts, :users 对 Rails 有什么影响吗?
K
Krule

对于前者,约定优于配置。当您引用另一个表时,Rails 默认为

 belongs_to :something

是寻找something_id

referencesbelongs_to 实际上是写前者的较新方式,几乎没有怪癖。

重要的是要记住它不会为您创建外键。为此,您需要使用以下任一方法显式设置它:

t.references :something, foreign_key: true
t.belongs_to :something_else, foreign_key: true

或(注意复数):

add_foreign_key :table_name, :somethings
add_foreign_key :table_name, :something_elses`

你能解释一下引用不会为你创建外键是什么意思吗?它与直接使用 user_id:integer 的第一个命令有何不同?
不是,除非您使用 :polymorphic 选项(恕我直言,在大多数情况下,这不是一个好主意)。如果要在 ActiveRecord 中使用外键,请使用 foreigner
@Krule Now add_foreign_key 已进入 ActiveRecord。