Ruby on rails 为什么在Rails 4中,连接表会出现未知的主键异常?

Ruby on rails 为什么在Rails 4中,连接表会出现未知的主键异常?,ruby-on-rails,exception,activerecord,ruby-on-rails-4,jointable,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 e

这些是我的模型:

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\u items
,它将抛出异常“model LineItem中表line\u items的主键未知”。
@order.products
按预期工作

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


以下是。

在模型中添加以下内容:

self.primary_key = [:order_id, :product_id]
我认为确保这些列上有
索引是明智的

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

add_index :line_items, [:order_id, :product_id]
  def change
    create_table :line_items do |t|
      t.references :order
      t.references :product
      t.integer :quantity
      t.timestamps
    end
  end

接受的答案已删除错误消息,但我仍然无法保存@order.line\u项目,而不会收到错误,告诉我[:order\u id,:product\u id]不存在

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

add_index :line_items, [:order_id, :product_id]
  def change
    create_table :line_items do |t|
      t.references :order
      t.references :product
      t.integer :quantity
      t.timestamps
    end
  end

最初创建表时我没有使用“references”,Rails 3并不介意,但Rails 4对此表示不满。

原始模式中的
id:false
表示表中没有
id
字段。Rails 4添加了一个
create\u join\u table
helper方法,该方法创建没有
id
字段的表,并将其用于名称中带有
JoinTable
的任何迁移

我可以想象,Rails 4得到的结果与Rails 3不同的唯一方法是重新生成迁移,并使用名称中的
JoinTable
进行迁移。您是否仍然拥有Rails3中的模式?值得注意的是,对于联接表,它具有
id:false

至于主键,您可以将主键设置为数组,但它随后不起作用的原因是,
primary\u key=
方法每行将其参数盲目地转换为字符串


另请参阅及其链接。

我有此错误,但在运行带有heroku db转储的
pgu restore
之前,先用
rake db:drop
删除本地数据库,然后用
rake db:create
创建,然后用heroku db dump解决了此问题。

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


添加列:model,:id,:primary\u key

,因为没有主键?;)我认为您不需要使用类似于“
add_index:line_items,[:order_id,:product_id],primary:true”的内容来创建迁移,我应该提到,我的原始表有“add_index”line_items“,[“order_id”,“product_id”]”,但我在尝试删除和重新创建表时没有使用它。我刚才试着用“primary:true”来运行迁移,但它说它无法识别关键字“primary”。我在add_index的文档中找不到关于这个“primary”选项的任何信息。我猜它应该是primary,不知道如何通过rails添加非默认的主索引。让我用谷歌搜索一下“默认情况下,create_table将创建一个名为id的主键。您可以使用:primary_key选项更改主键的名称(不要忘记更新相应的模型)”,因此可能是
add_index:line_items,[:order_id,:product_id],主键:true
在Rails 4的指南中指出,模型没有猜测主键。也许他们把它从Rails 3改过来了?如果我对Rails如此了解,那就太好了:这不是正确的答案!
self.primary\u key=[:order\u id,:product\u id]
行是错误的,正如@Iala在自己的回答中所指出的,它将给出错误,因为活动记录不支持复合主键。如果你想增加对@jj_u的支持,这里有一块宝石。我很有信心这在一年前就成功了。OP还说它实际上是有效的,但Rails可能需要在这些列上建立索引。再看看我自己的问题和类似案例的答案,好吧,我甚至仔细检查了一下,你是对的。让我想知道连根拔起是如何工作的,没有人发布这是错误的?我在Heroku和Sidekiq worker中也遇到了同样的问题。我重新启动了所有的dyno,工作正常。