Rails中JoinTable迁移方法的模型类名

时间:2017-12-24 09:58:39

标签: ruby-on-rails rails-activerecord

here的Rails指南中,写道:

  

如果JoinTable是名称的一部分,还有一个生成连接表的生成器:

     

rails g migration CreateJoinTableCustomerProduct customer product

它生成:

class CreateJoinTableCustomerProduct < ActiveRecord::Migration[5.1]
  def change
    create_join_table :customers, :products do |t|
      # t.index [:customer_id, :product_id]
      # t.index [:product_id, :customer_id]
    end
  end
end

这只是创建customers_products表,两个单词都是复数。

当我创建一个模型CustomerProduct:

class CustomerProduct < ApplicationRecord
end

始终搜索customer_products而不是customers_products

ActiveRecord::StatementInvalid: Mysql2::Error: Table 'customer_products' doesn't exist

有没有办法让模型引用正确的表而不明确指定table_name或命名CustomersProduct :)?

值得一提的是,我希望将其用于:has_many :through而不是:has_and_belongs_to_many

另外,为什么在生成的迁移中,有两行添加不同顺序的索引?

# t.index [:customer_id, :product_id]
# t.index [:product_id, :customer_id]

1 个答案:

答案 0 :(得分:2)

我认为您应该根据基本的Rails命名约定命名您的“连接模型”并加入表。我个人喜欢的方式是用自己的单词命名连接表(而不是其他两个表的单词)。与customers_products不同,但selected_product甚至customer_product之类的东西都会做。在这些情况下,您的模型会正确搜索表格(selected_productscustomer_products)。

关于索引。对于复合索引,列的顺序很重要。基本上如果你有t.index [:customer_id, :product_id]

CustomerProduct.where(customer_id: 5, product_id: 6)将使用您的索引

CustomerProduct.where(customer_id: 5)将使用您的索引,但

CustomerProduct.where(product_id: 5)即使索引中包含product_id

,也不会使用该索引

因此,如果您要在所有组合中按两列查询您的表,则需要这两个复合索引。您可以通过添加索引并尝试EXPLAIN ANALYZE来了解查询将如何使用索引来查看它。