我是否可以使用2个字段生成迁移,这些字段将在同一个表中引用?

时间:2016-02-25 11:39:09

标签: ruby-on-rails migration

我想在表格中添加订单两个字段: seller_id buyer_id ,它们将引用用户表。
我不确定这样做的最佳方法是什么?

  1. rails g migration AddUsersToOrder seller_id:integer buyer:integer
    我可以运行这个命令,但是我认为这不是一个好的解决方案,因为这个命令并没有连接'这两个表,它只创建两个没有 FOREIGN KEY约束的整数字段。换句话说,不会创建引用,但肯定会有效。
  2. 有一个相当不错的article(但是从2008年开始)与相同的例子有关但它不会产生迁移,而是侧重于模型。 同样@Joe Kennedy为一个类似的问题写了一篇非常好的solution。但正如我所说,我认为这不会创建参考。

    1. rails g migration AddUserRefToOrder seller_id:references
      这是最好的方法,但问题是我们无法通过这种方式为买方创建另一种迁移。


    2. 我想知道我该怎么办我错过了什么?

1 个答案:

答案 0 :(得分:2)

取决于您希望如何与2种版本中可选择的内容进行互动。

对于任务,重要的是要看谁是分配者/执行者,这样我才能对不同的(传入/传出)任务进行排序。我可以致电user.assigned_tasksuser.executed_tasks

对于对话,我对与该模型进行交互不感兴趣。谁创造它并不重要。我不需要conversation.senderconversation.recipient。我需要根据发件人/收件人识别消息(嵌套在会话中)。

版本A

class Task < ActiveRecord::Base
  belongs_to :assigner, class_name: "User"
  belongs_to :executor, class_name: "User"
end

class User < ActiveRecord::Base
  has_many :assigned_tasks, class_name: "Task", foreign_key: "assigner_id", dependent: :destroy
  has_many :executed_tasks, class_name: "Task", foreign_key: "executor_id", dependent: :destroy
end

create_table "tasks", force: :cascade do |t|
   t.integer  "assigner_id"
   t.integer  "executor_id"
end
add_index "tasks", ["assigner_id"], name: "index_tasks_on_assigner_id", using: :btree
add_index "tasks", ["executor_id"], name: "index_tasks_on_executor_id", using: :btree

版本B

class User < ActiveRecord::Base
  has_many :conversations, foreign_key: "sender_id", dependent: :destroy
end

class Conversation < ActiveRecord::Base
  belongs_to :sender, class_name: "User", foreign_key: "sender_id"
  belongs_to :recipient, class_name: "User", foreign_key: "recipient_id"
end

create_table "conversations", force: :cascade do |t|
  t.integer  "sender_id"
  t.integer  "recipient_id"
end
add_index "conversations", ["recipient_id"], name: "index_conversations_on_recipient_id", using: :btree
add_index "conversations", ["sender_id"], name: "index_conversations_on_sender_id", using: :btree

更新:

如果您运行rails g model Userrails g model Order,也会沿着测试文件,模型文件等生成迁移。如果该表尚不存在,这是首选方法。如果表已经存在并且您想要更改它,那么您只创建可以通过两种方式完成的迁移。第一个是你在谈论你也传递参数的地方,所以当你打开迁移文件时,列已经存在了。但这是艰难的方式。您只需运行rails g migration AddSomethingToThis即可。迁移名称无关紧要,您只需选择描述性内容,以便以后轻松识别迁移文件。然后打开迁移文件,然后在那里放置所需的列。在我的代码中,您会看到必要的foreign keys。除此之外,您还可以创建价格列等,您的业务逻辑需要什么。然后运行rake db:migrate,这将更改您的数据库架构。您始终可以在schema.rb中查看当前架构。切勿仅通过迁移手动更改架构。

总结:

  1. 创建迁移(如果还没有表,则使用模型)
  2. 编辑迁移文件
  3. 运行rake db:migrate,以便更新架构。
  4. 更新2:

    您可以在迁移文件中添加t.integer "recipient_id", index :true,然后在运行{{ 1}}。查看一些迁移示例。

    因此索引与性能有关。对于索引,在大多数情况下,db中的搜索速度更快。它就像书中的书签一样。通常将它添加到外键,因为它们是两个模型之间的桥梁。如果模型中有一些属性被大量查询,那么您也可以将它们添加到那些属性中。不要添加太多行。您可以想象当您将20个书签添加到书中时会发生什么。