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

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

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的外键?谢谢!

161709 次浏览

在运行迁移时,两者都将生成相同的列。在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列上添加了一个索引。

对于前者,约定优于配置。使用引用另一个表时,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`

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

< p > 仅供参考 < br > 使用前一种方法声明外键只让Rails知道模型/表之间的关系。数据库不知道该关系。因此,当你使用像MySql Workbench这样的软件生成EER图时,你会发现模型之间没有关系线程。就像下面的图片 enter image description here < / p >

然而,如果你使用后面的方法,你会发现你的迁移文件看起来像:

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


t.timestamps null: false
end
add_foreign_key :microposts, :users
现在外键被设置在数据库级别。并且你可以生成适当的EER图。 enter image description here < / p >