在Rails 4迁移中设置自定义主键的问题

7

我使用postgresql 9.3、Ruby 2.0和Rails 4.0.0。

在阅读了许多有关设置表主键的SO问题后,我生成并添加了以下迁移:

class CreateShareholders < ActiveRecord::Migration
  def change
    create_table :shareholders, { id: false, primary_key: :uid  } do |t|
      t.integer :uid, limit: 8
      t.string :name
      t.integer :shares

      t.timestamps
    end
  end
end

我还在我的模型中添加了self.primary_key = "uid"

迁移成功运行,但是当我使用pgAdmin III连接到数据库时,我发现uid列没有被设置为主键。我错过了什么吗?

3个回答

19
请看这个答案。尝试在create_table块中不指定primary_key参数执行“ALTER TABLE shareholders ADD PRIMARY KEY (uid);”。
我建议您按照以下方式编写迁移(这样您就可以正常回滚):
class CreateShareholders < ActiveRecord::Migration
  def up
    create_table :shareholders, id: false do |t|
      t.integer :uid, limit: 8
      t.string :name
      t.integer :shares

      t.timestamps
    end
    execute "ALTER TABLE shareholders ADD PRIMARY KEY (uid);"
  end

  def down
    drop_table :shareholders
  end
end

更新:这里有一种自然的方法(在这里找到),但仅适用于int4类型:

class CreateShareholders < ActiveRecord::Migration
  def change
    create_table :shareholders, id: false do |t|
      t.primary_key :uid
      t.string :name
      t.integer :shares

      t.timestamps
    end    
  end
end

这正是我在问题中遗漏的内容。虽然我能够做到这一点,但我想知道是否有一种“自然”的方法来实现这一点,即不执行直接的SQL查询。尽管没有其他建议,但我仍然接受这个答案作为最佳答案。 :) - Alexander Popov
但在这种情况下,主键的类型是什么?我需要它是bigint。 - Alexander Popov
抱歉,我错过了。它是int4。然而,这种方式不适合我们。 - peresleguine
1
由于“primary_key”方法只接受一个参数,我认为除了使用纯SQL进行bigint之外别无选择。 - peresleguine
默认情况下,Rails 5.1中的主键是bigint:github.com/rails/rails/pull/26266 - bkdir
我无法为此点赞足够。我们已经到了Rails 7,但它的文档中仍然没有提及如果您不想在表上使用id作为主键列的情况。 - ortonomy

1
在我的环境中(activerecord 3.2.19和postgres 9.3.1),
:id => true, :primary_key => "columname"

成功创建了一个主键,但是列的类型是 int4,而不是指定的":limit => 8"。
create_table :m_check_pattern, :primary_key => "checkpatternid" do |t|
  t.integer     :checkpatternid, :limit => 8, :null => false
end

抱歉信息不完整。

0

我已经创建了这样的迁移:

class CreateShareholders < ActiveRecord::Migration
  def change
    create_table :shareholders, id: false do |t|
      t.integer :uid, primary_key: true
      t.string :name
      t.integer :shares

      t.timestamps
    end    
  end
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接