【问题标题】:has_many, belongs_to relation in active record migration rails 4has_many,belongs_to 活动记录迁移 rails 4 中的关系
【发布时间】:2013-07-27 12:15:17
【问题描述】:

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

我需要通过迁移确定 User has_many TasksTask belongs_to User

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

【问题讨论】:

标签: ruby-on-rails rails-activerecord ruby-on-rails-4 rails-migrations


【解决方案1】:

你可以打电话:

rails g model task user:references

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

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

rails g migration AddUserToTask user:belongs_to

将生成:

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

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

【讨论】:

  • 我想最好注意 :belongs_to 是 :references 的别名。不过答案很好。 :)
【解决方案2】:

要回答这个问题,“建立这种关系的迁移生成命令是什么?”(意思是,您如何为现有模型添加迁移,关系类似于User has_many TasksTask 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

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

【讨论】:

    【解决方案3】:

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

    rails g scaffold child parent:references


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

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

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

    选项 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 guide to association 提供有关该主题的更多信息。

    【讨论】:

      【解决方案4】:

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

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

      class User < ActiveRecord::Base
        has_many :tasks
      end
      
      class Task < ActiveRecord::Base
        belongs_to :user
      end
      

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

      看看这个guide

      【讨论】:

      • 这很好,但是如果表用户在创建任务表时没有包含t.references :user,那么这个^将不起作用。
      【解决方案5】:

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

      rails g migration AddUserIdToTask user_id:integer
      

      然后

      rake db:migrate
      

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

      【讨论】:

      • 这有点小题大做,您应该确保在定义表格时使用t.references :user。或者,如果已经创建了没有它的表,请编写一个迁移来为您执行此操作。
      【解决方案6】:

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

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

      class User < ActiveRecord::Base
        has_many :tasks
      end
      
      class Task < ActiveRecord::Base
        belongs_to :user
      end
      

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

      【讨论】:

      • yes jha.. 我可以补充一下,只是想知道终端中的迁移命令。
      • 在这种情况下,只需运行 rails generate migration add_user_id_to_task。它将从您那里生成迁移文件,您可以在此处添加和删除列
      • rails g migration AddUserIdToTask user_id:integer
      猜你喜欢
      • 2013-09-11
      • 1970-01-01
      • 2014-10-23
      • 1970-01-01
      • 1970-01-01
      • 2015-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多