69

我有一个User模型和一个Task模型。在创建它们时,我没有提到它们之间的任何关系。

我需要通过迁移 来确定这User has_many Tasks一点Task belongs_to User

建立这种关系的迁移生成命令是什么?

4

6 回答 6

88

您可以致电:

rails g model task user:references

这将在表中生成一user_id列,tasks并将修改task.rb模型以添加belongs_to :user关系。请注意,您必须手动将has_many :tasksor has_one :task关系放入user.rb模型。

如果您已经生成了模型,则可以使用以下内容创建迁移:

rails g migration AddUserToTask user:belongs_to

这将产生:

class AddUserToTask < ActiveRecord::Migration
  def change
    add_reference :tasks, :user, index: true
  end
end

这种方法的唯一区别是,模型belongs_to :user中的关系task.rb不会自动创建,因此您必须自己创建它。

于 2013-07-29T15:30:42.380 回答
31

要回答这个问题,“建立这种关系的迁移生成命令是什么?”(意思是,你如何为具有类似User has_many Tasks&关系的现有模型添加迁移Task belongs_to User

我最容易记住的方法是这样的:

>rails g migration AddUserToTask user:belongs_to

或者

>rails g migration AddUserToTask user:references

:belongs_to只是 的别名:references,所以两者都会做同样的事情。

这样做,该命令将从迁移名称推断表的名称,设置一个更改方法,该方法将添加关系列,并将其配置为索引:

class AddUserToTask < ActiveRecord::Migration
  def change
    add_reference :tasks, :user, index: true
  end
end

生成后,您:

>rake db:migrate

最后,您仍然必须将通常的关系添加到您的模型中,如其他答案中所述,但我认为这是您问题的正确答案。

于 2014-09-22T19:32:05.950 回答
18

这是正常创建迁移的方式:

rails g scaffold child parent:references


建表时忘记添加parent:references了,怎么办?

选项 1:销毁表并重新开始

如果您没有在模型/数据库中定义很多关于子表的内容。你最好的选择可能是跑rails destroy scaffold child,然后跑 rails g scaffold child parent:references过去。确保drop_table :children if table_exists? :children在创建新表的文件中的 create table 之前添加该行。(这样,如果有人提取您的代码,他们就可以运行迁移并完成。)但是,您似乎更有可能已经拥有不想在子模型中丢失的数据。在这种情况下:

选项 2:编写迁移以添加引用

rails g migration add_parent_refs_to_child

## XXXXXXXXXXXXXX_add_parent_refs_to_child.rb
class AddParentRefsToChild < ActiveRecord::Migration
  def change
    add_reference :child, :parent, index: true
  end
end

add_reference

此外,不要忘记确保父模型has_[one | many] :children和子模型belongs_to :parent


如何不这样做:

您可能很想parent_id手动添加。不。通常,此类操作是通过迁移或在初始表创建中处理的。手动添加会降低项目的可维护性。

Ruby on Rails 关联指南提供了有关该主题的更多信息。

于 2014-10-01T14:57:36.633 回答
5

没有可以使用的特殊迁移命令。

在您的用户模型中,您将放置

class User < ActiveRecord::Base
  has_many :tasks
end

class Task < ActiveRecord::Base
  belongs_to :user
end

在任务的相应迁移文件中,您添加了以下字段 user_id

看看这个指南

于 2013-07-27T06:01:16.703 回答
4

Rails 中的关系由模型而不是 Rails 处理。

所以你只需要在你的模型中定义这种关系:

class User < ActiveRecord::Base
  has_many :tasks
end

class Task < ActiveRecord::Base
  belongs_to :user
end

并且只需确保user_id迁移中存在用于创建“任务”表的字段。

于 2013-07-27T05:59:51.733 回答
4

迁移会将用户的 id 添加到任务表中,以便他们彼此了解

rails g migration AddUserIdToTask user_id:integer

然后

rake db:migrate

并且在更新您的控制器和视图之后,任务不能自己创建,但必须对应于用户

于 2013-11-18T07:15:58.287 回答