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

时间:2013-07-13 13:38:05

标签: ruby-on-rails exception activerecord ruby-on-rails-4 jointable

这些是我的模特:

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,则会抛出异常“模型LineItem中的表line_items的未知主键”。 @order.products按预期工作。

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

这是the trace

5 个答案:

答案 0 :(得分:15)

在模型中添加

self.primary_key = [:order_id, :product_id]

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

add_index :line_items, [:order_id, :product_id]

答案 1 :(得分:8)

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

我能想象你使用Rails 4而不是使用Rails 3获得不同结果的唯一方法是重新创建迁移并在名称中迁移JoinTable。你还有Rails 3的架构吗?值得注意的是,它对于连接表有id: false

至于primary_key,你可以将主键设置为数组但后来不起作用的原因是因为primary_key=方法盲目地将其参数转换为{{3}的每行115的字符串}

另请参阅https://github.com/rails/rails/blob/a0dfd84440f28d2862b7eb7ea340ca28d98fb23f/activerecord/lib/active_record/attribute_methods/primary_key.rb#L115及其链接。

答案 2 :(得分:4)

删除id: false应该可以解决您的错误。 为此,请使用以下行进行迁移:

add_column :model, :id, :primary_key

答案 3 :(得分:2)

接受的答案消除了错误消息,但我仍然无法保存@ 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抱怨。

答案 4 :(得分:0)

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