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

时间:2021-10-18 12:09:59

These are my models:

这些是我的模特:

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

From 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

I just upgraded to Rails 4, and my join table stopped working. If I do @order.line_items, it throws the exception "Unknown primary key for table line_items in model LineItem." @order.products works as expected.

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

I have tried dropping and recreating the line_items table, and I have tried installing the protected_attributes gem, but nothing changed.

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

Here is the trace.

这是跟踪。

5 个解决方案

#1


12  

In model add

在模型添加

self.primary_key = [:order_id, :product_id]

and I think it would be wise to ensure that there's an index on those columns. You may create one with following migration

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

add_index :line_items, [:order_id, :product_id]

#2


7  

The id: false in your original schema indicates that there is no id field in the table. Rails 4 added a create_join_table helper method which creates tables with no id field and uses this for any migration with JoinTable in the name.

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

The only way I can imagine that you're getting difference results with Rails 4 than with Rails 3 is if you regenerated your migrations and had a migration with JoinTable in the name. Do you still have your schema from Rails 3 around? It would be interesting to note it has id: false for the join table.

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

As for the primary_key, the reason you could set the primary key to an array but it subsequently didn't work is because the primary_key= method blindly converts its argument to a string per line 115 of https://github.com/rails/rails/blob/a0dfd84440f28d2862b7eb7ea340ca28d98fb23f/activerecord/lib/active_record/attribute_methods/primary_key.rb#L115

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

See also https://*.com/a/20016034/1008891 and its links.

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

#3


2  

The accepted answer got rid of the error message, but I was still unable to save @order.line_items without getting an error telling me [:order_id, :product_id] does not exist.

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

I finally solved this by deleting the line_items table and recreating it with this migration:

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

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

I hadn't used "references" when I created the table originally, which Rails 3 didn't mind, but made Rails 4 complain.

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

#4


1  

Removing the id: false should fix your error. To do that, make a migration with the following line:

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

add_column :model, :id, :primary_key

add_column:model,:id,:primary_key

#5


0  

I had this error, but dropping my local database with rake db:drop and then creating with rake db:create before running pg_restore with the heroku db dump solved it.

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

#1


12  

In model add

在模型添加

self.primary_key = [:order_id, :product_id]

and I think it would be wise to ensure that there's an index on those columns. You may create one with following migration

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

add_index :line_items, [:order_id, :product_id]

#2


7  

The id: false in your original schema indicates that there is no id field in the table. Rails 4 added a create_join_table helper method which creates tables with no id field and uses this for any migration with JoinTable in the name.

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

The only way I can imagine that you're getting difference results with Rails 4 than with Rails 3 is if you regenerated your migrations and had a migration with JoinTable in the name. Do you still have your schema from Rails 3 around? It would be interesting to note it has id: false for the join table.

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

As for the primary_key, the reason you could set the primary key to an array but it subsequently didn't work is because the primary_key= method blindly converts its argument to a string per line 115 of https://github.com/rails/rails/blob/a0dfd84440f28d2862b7eb7ea340ca28d98fb23f/activerecord/lib/active_record/attribute_methods/primary_key.rb#L115

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

See also https://*.com/a/20016034/1008891 and its links.

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

#3


2  

The accepted answer got rid of the error message, but I was still unable to save @order.line_items without getting an error telling me [:order_id, :product_id] does not exist.

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

I finally solved this by deleting the line_items table and recreating it with this migration:

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

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

I hadn't used "references" when I created the table originally, which Rails 3 didn't mind, but made Rails 4 complain.

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

#4


1  

Removing the id: false should fix your error. To do that, make a migration with the following line:

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

add_column :model, :id, :primary_key

add_column:model,:id,:primary_key

#5


0  

I had this error, but dropping my local database with rake db:drop and then creating with rake db:create before running pg_restore with the heroku db dump solved it.

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