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

Posted

技术标签:

【中文标题】在 Rails 中使用 user_id:integer 与 user:references 生成模型【英文标题】:Generate model in Rails using user_id:integer vs user:references 【发布时间】:2011-12-13 07:14:20 【问题描述】:

我对如何生成一个属于另一个模型的模型感到困惑。我的书使用这种语法将 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 的外键?谢谢!

【问题讨论】:

【参考方案1】:

在您运行迁移时,两者都会生成相同的列。在 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 会在外键上创建索引,而手动创建列不会?【参考方案2】:

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

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 行,并在此声明为外键。

仅供参考 使用前一种方法声明外键只会让 Rails 知道模型/表之间的关系。数据库对于这种关系是未知的。因此,当您使用mysql Workbench 之类的软件生成 EER 图时,您会发现模型之间没有绘制任何关系线程。如下图所示

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

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

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

现在外键设置在数据库级别。并且您可以生成正确的EER 图表。

【讨论】:

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

对于前者,约定优于配置。当您使用

引用另一个表时,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。

以上是关于在 Rails 中使用 user_id:integer 与 user:references 生成模型的主要内容,如果未能解决你的问题,请参考以下文章

Rails:在 Rails 视图中使用 javascript 函数的正确语法

如何在 Webpacker 中使用 Rails Url 助手/Rails 5.1 中的 React-rails

在 gem 中使用 rails 作为依赖项

在 rake 任务中使用 rails logger,rails 5

在 JS 模块中使用 Rails-UJS(带有 webpacker 的 Rails 6)

Rails 3:在 Rails 中使用 JSON 响应 REST-ful 操作的正确方法是啥?