Heroku,Postgresql,composite_primary_keys

时间:2012-05-31 21:55:35

标签: ruby-on-rails ruby postgresql activerecord heroku

我有一个正在研究的Rails 3应用程序。我正在使用composite_primary_keys gem来表示一些表,但Rails仍在创建一个未被使用的id字段(即每个条目的nil为n)。当它在SQLite3中的本地计算机上运行时,我无法在Heroku上运行该应用程序。 Postgresql对我不适合给我这个错误:

2012-05-31T21:12:36+00:00 app[web.1]: ActiveRecord::StatementInvalid (PG::Error: ERROR:  null value in column "id" violates not-null constraint
2012-05-31T21:12:36+00:00 app[web.1]:   app/controllers/items_controller.rb:57:in `block (2 levels) in create'
2012-05-31T21:12:36+00:00 app[web.1]: : INSERT INTO "item_attr_quants" ("attribute_id", "created_at", "id", "item_id", "updated_at", "value") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "item_id","attribute_id"):

由于“id”字段为零,Postgresql对我大喊大叫。

有没有办法可以防止首先创建“id”字段,使用原始SQL语句删除列,强制Heroku上的Postgresql允许“id”字段为null,或者绕过这有其他方式吗?我已经死定了使用复合主键,因此我不想删除gem并重写代码。

模型

class ItemAttrQuant < ActiveRecord::Base
  belongs_to :item
  belongs_to :attribute
  self.primary_keys = :item_id, :attribute_id
end

移植

class CreateItemAttrQuants < ActiveRecord::Migration
  def change
    create_table :item_attr_quants do |t|
      t.belongs_to :item
      t.belongs_to :attribute
      t.integer :value

      t.timestamps
    end
    add_index :item_attr_quants, :item_id
    add_index :item_attr_quants, :attribute_id
  end
end

1 个答案:

答案 0 :(得分:1)

您可以在迁移中使用:id => false:primary_key选项create_table

class CreateItemAttrQuants < ActiveRecord::Migration
  def change
    create_table :item_attr_quants, :id => false do |t|
      ...
    end
    ...
  end
end

这将创建没有item_attr_quants列的id,但您的表将没有真正的主键。您可以通过为not nullitem_id指定attribute_id并在这两列添加唯一索引来添加假冒的内容:

class CreateItemAttrQuants < ActiveRecord::Migration
  def change
    create_table :item_attr_quants, :id => false do |t|
      t.integer :item_id, :null => false
      t.integer :attribute_id, :null => false
      t.integer :value
      t.timestamps
    end
    add_index :item_attr_quants, [:item_id, :attribute_id], :unique => true
    add_index :item_attr_quants, :item_id
    add_index :item_attr_quants, :attribute_id
  end
end

我认为ActiveRecord并不完全理解数据库中真正的复合主键的概念,因此除非您想要将ALTER TABLE手动发送到数据库中,否则唯一的索引就是AFAIK,你可以做到最好。