【问题标题】:Need to use add_index on migration for belongs_to/has_many relationship? (Rails 3.2, Active Record)需要在迁移时使用 add_index 来处理 belongs_to/has_many 关系? (Rails 3.2,活动记录)
【发布时间】:2013-09-11 11:08:12
【问题描述】:

我的问题很简单,但我没有找到明确的答案。

我构建了一个每日交易 Rails 应用程序。

  • 每笔交易都有很多产品 (has_many)

  • 每个产品都属于一个交易

Rails Guides 的 2.3 之后,我将在迁移中使用它:

   class CreateDeal < ActiveRecord::Migration
    def change
      create_table :deals do |t|
        t.string :name
        t.timestamps
      end

      create_table :products do |t|
        t.belongs_to :Deal
        t.timestamps
      end
    end
   end

Rails/active 记录会自动在 Product Table 中添加一列 Deals_id 对吧?

我是否需要通过添加到我的迁移add_index 来手动(如下所示)在此 deal_id 列上添加索引,还是由于我设置的 belongs_to/has_many 关系而“自动”完成?

create_table :products do |t|
  t.belongs_to :Deal
  t.timestamps

  add_index :products, :deals_id 
end

【问题讨论】:

  • 不应该 t.belongs_to :Dealt.belongs_to :deal

标签: ruby-on-rails ruby ruby-on-rails-3 activerecord


【解决方案1】:

您确实需要自己添加索引...但是,如果您使用模型的命令行生成器并使用belongs_to,Rails 会将索引添加到迁移中...

例如

rails g model product deal:belongs_to

会产生

class CreateProducts < ActiveRecord::Migration
  def change
    create table :products do |t|
      t.belongs_to :deal

      t.timestamps
    end
    add_index :products, :deal_id
  end
end

【讨论】:

    【解决方案2】:

    您需要自己添加索引。

    此外,您的迁移也不太正确,您需要第三张表,即:

    class CreateDeal < ActiveRecord::Migration
      def change
        create_table :deals do |t|
          t.string :name
          t.timestamps
        end
    
        create_table :products do |t|
          t.string :title
          t.timestamps
        end
    
        create_table :deals_products do |t|
          t.belongs_to :deal
          t.belongs_to :product
        end
      end
    end
    

    根据http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association

    【讨论】:

    • 这是多对多关系的设置,而不是 Mathieu 所说的简单的 has_many 关系。除非您确实需要多对多关联,否则我个人会避免此设置,因为通过此设置,您有 3 个表需要 2 个索引(未在此迁移中),而不是 2 个表和一个索引。据我了解,虽然索引可以加快查询速度,但它们会使保存/更新过程花费更长的时间,因此通常最好将它们的使用减少到仅在需要它们以减少开销时才使用。在这种情况下,似乎一个索引就足够了。
    • 是的,我的错误 - 我不知道我从哪里得知他使用的是多对多 from。
    【解决方案3】:

    Mathieu,在这种有疑问的情况下,您不确定是否正在创建某些东西:似乎最好只明确创建您认为需要的内容(在本例中为索引),然后看看会发生什么当您运行迁移时。

    这背后的逻辑是,如果您的 :deal_id 列已经被索引并且您的迁移尝试重新索引它,它将得到一个错误并且迁移将回滚以便您可以修复它。但是,如果您没有在迁移中添加索引,您显然不会收到任何错误,但您必须采取额外的步骤来检查索引是否存在。

    class CreateDeal < ActiveRecord::Migration
      def change
        create_table :deals do |t|
          t.string :name
          t.timestamps
        end
    
        create_table :products do |t|
          t.belongs_to :Deal
          t.timestamps
        end
    
        add_index :products, :deal_id
      end
    end
    

    请注意,您还希望在表创建过程完成后添加索引。在 create_table 助手中使用 add_index 助手可能会导致错误。

    【讨论】:

      猜你喜欢
      • 2013-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-26
      • 2014-10-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多