Why do I get an Unknown Primary Key exception for a join table in Rails 4?

天大地大妈咪最大 提交于 2019-11-30 16:47:06

问题


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.

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

Here is the trace.


回答1:


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:


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.

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.

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

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




回答3:


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

add_column :model, :id, :primary_key




回答4:


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.

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

  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.




回答5:


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.



来源:https://stackoverflow.com/questions/17630714/why-do-i-get-an-unknown-primary-key-exception-for-a-join-table-in-rails-4

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!