12

这些是我的模型:

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,但没有任何改变。

这是痕迹

4

5 回答 5

18

在模型中添加以下内容:

self.primary_key = [:order_id, :product_id]

我认为确保index这些列上有一个是明智的。

您可以通过以下迁移创建一个:

add_index :line_items, [:order_id, :product_id]
于 2013-07-13T14:10:29.337 回答
9

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

我可以想象你使用 Rails 4 得到的结果与使用 Rails 3 不同的唯一方法是,如果你重新生成了迁移并JoinTable在名称中进行了迁移。你还有 Rails 3 的架构吗?值得注意的是它对id: false连接表有影响。

至于primary_key,您可以将主键设置为数组但随后不起作用的原因是该方法盲目地将其参数转换为https://github.com/rails/rails/primary_key=的第115行的字符串blob/a0dfd84440f28d2862b7eb7ea340ca28d98fb23f/activerecord/lib/active_record/attribute_methods/primary_key.rb#L115

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

于 2013-11-16T07:54:59.943 回答
4

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

add_column :model, :id, :primary_key

于 2018-03-10T10:37:26.743 回答
3

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

于 2013-07-16T14:23:38.940 回答
0

我遇到了这个错误,但是在使用 heroku db dump运行之前删除我的本地数据库rake db:drop然后创建它解决了它。rake db:createpg_restore

于 2017-12-11T17:47:18.390 回答