为什么我在Rails 4中获得连接表的未知主键例外?

这些是我的模特:

class Product has_many :line_items has_many :orders, :through => :line_items end class LineItem belongs_to :order belongs_to :product end class Order has_many :line_items has_many :products, :through => :line_items end 

来自schema.rb:

  create_table "line_items", id: false, force: true do |t| t.integer "order_id" t.integer "product_id" t.integer "quantity" t.datetime "created_at" t.datetime "updated_at" end 

我刚刚升级到Rails 4,我的连接表停止工作。 如果我执行@order.line_items ,它会抛出exception“模型LineItem中的表line_items的未知主键”。 @order.products按预期工作。

我已经尝试删除并重新创建line_items表,我已经尝试安装protected_attributes gem,但没有任何改变。

这是跟踪 。

在模型添加

 self.primary_key = [:order_id, :product_id] 

我认为确保这些列上有索引是明智的。 您可以使用以下迁移创建一个

 add_index :line_items, [:order_id, :product_id] 

原始模式中的id: false表示表中没有id字段。 Rails 4添加了一个create_join_table辅助方法,该方法创建没有id字段的表,并将其用于名称中包含JoinTable任何迁移。

我可以想象你使用Rails 4而不是使用Rails 3获得差异的唯一方法就是重新生成迁移并在名称中使用JoinTable进行迁移。 你还有Rails 3的架构吗? 值得注意的是,对于连接表,它具有id: false

至于primary_key,你可以将主键设置为数组但后来不起作用的原因是因为primary_key=方法盲目地将其参数转换为https://github.com/rails/的每行115的字符串导轨/ BLOB / a0dfd84440f28d2862b7eb7ea340ca28d98fb23f / ActiveRecord的/ lib目录/ active_record / attribute_methods / primary_key.rb#L115

另请参见https://stackoverflow.com/a/20016034/1008891及其链接。

接受的答案消除了错误消息,但我仍然无法保存@ order.line_items而没有收到错误告诉我[:order_id,:product_id]不存在。

我最后通过删除line_items表并使用此迁移重新创建它来解决此问题:

  def change create_table :line_items do |t| t.references :order t.references :product t.integer :quantity t.timestamps end end 

我最初创建表时没有使用“引用”,Rails 3并不介意,但让Rails 4抱怨。

删除id: false应修复错误。 为此,请使用以下行进行迁移:

add_column :model, :id, :primary_key

我有这个错误,但是使用rake db:drop删除我的本地数据库,然后使用rake db:create然后使用heroku db dump运行pg_restore解决了它。