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


175

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

rails generate model Micropost user_id:integer

http://guides.rubyonrails.org/表示要这样做:

rails generate model Micropost user:references

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

Answers:


190

运行迁移时,两者都会生成相同的列。在Rails控制台中,可以看到是这种情况:

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

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

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


1
是否有可能使用两个表的引用生成模型
praveenkumar

请注意,它不会在其他模型(用户)上添加has_many关联,您可能也想添加该关联。
Sv1

45

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_idUser模型的外键。

后来的命令rails generate model Micropost user:references添加行belongs_to :userMicropost模型,并在此声明为外键。

仅供参考
,使用前一种方法声明外键只能使Rails知道模型/表之间的关系。该数据库未知该关系。因此,当您使用类似软件生成EER图时MySql Workbench,发现在模型之间没有绘制关系线程。就像下面的图片一样 在此处输入图片说明

但是,如果使用后面的方法,则会发现迁移文件看起来像:

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

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

现在,外键已在数据库级别设置。您可以生成适当的EER图表。 在此处输入图片说明


1
似乎最新的Rails生成器用该行add_foreign_key的选项替换了action ,这意味着。现在是这样。当前没有有关该选项的文档,因此这只是我的假设。foreign_key: truet.referencesindex: truet.references :user, foreign_key: trueforeign_key
富兰克林于

哦,add_reference操作有一个:foreign_key选项,可以添加适当的外键约束。我猜这个选项在创建表时会做同样的事情。
富兰克林于

如何将红宝石数据库导出到工作台?您能在这里回答这个问题吗:stackoverflow.com/questions/42982921/…–
Krawalla

是否有add_foreign_key :microposts, :users 让Rails的有什么区别?
莱纳斯(Linus)

17

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

 belongs_to :something

是寻找something_id

references,或者belongs_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`

1
您能通过说引用不会为您创建外键来解释您的意思吗?与直接使用user_id:integer的第一个命令有何不同?
shailesh

并非如此,除非您正在使用:polymorphic选项(在大多数情况下,恕我直言,这不是一个好主意)。如果要在ActiveRecord中使用外键,请使用foreigner
克鲁

1
@Krule Now add_foreign_key已将其放入ActiveRecord。
富兰克林于
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.