这是问题I asked before的构建(没有任何运气)。
我有一个模型,我使用字符串作为主键:
class Employee < ActiveRecord::Base
self.primary_key = "employment_id"
end
此表还包含Rails默认的“id”字段,具有唯一性约束。
当我在本地添加新员工时,一切正常,Rails会自动生成一个新的唯一ID。
然而,当我在Heroku Postgres上运行它时,似乎将'id'和'employment_id'视为同一个字段。我尝试通过手动设置唯一ID来解决这个问题,但仍然会出现这种情况:
Employee.new do |s|
max_id = Employee.maximum(:id)
puts max_id.to_s # => 1803
s.employment_id = "fred_01"
s.id = max_id + 1
puts employment_id.to_s # => 1804
end
我在本地运行postgres 9.1.3(Heroku在9.1.4上运行)。我在Rails 3.2.3上。
我的问题是:
感谢您的帮助!
德里克。
修改
按要求添加迁移文件:
class CreateEmployees < ActiveRecord::Migration
def change
create_table :employees do |t|
t.string :employment_id, :unique => true
etc...
end
end
end
修改
很多人没有人指出这一点,但我现在很清楚,真正的答案是“只因为你可以,并不意味着你应该!”
答案 0 :(得分:1)
根据this帖子,它应该解决问题:
class CreateEmployees < ActiveRecord::Migration
def change
create_table :employees, {:id => false} do |t|
t.string :employment_id, :unique => true
etc...
end
end
execute "ALTER TABLE employees ADD PRIMARY KEY (employment_id);"
end
同样在你的模特中:
class Employee < ActiveRecord::Base
set_primary_key :employment_id
...
end
答案 1 :(得分:1)
Rails 4.2.0和Postgres的更新,以防有人帮助......
在id: :string
选项中添加create_table
:
class FooMigration < ActiveRecord::Migration
def change
create_table :foo, id: :string do |t|
t.string :name, null: false
t.timestamps null: false
end
end
end
rake db:migrate
== 20150225043441 FooMigration: migrating ===========================
-- create_table(:foo, {:id=>:string}) -> 0.0031s
== 20150225043441 FooMigration: migrated (0.0032s) ==================
rails db(和\ d foo)
psql (9.3.6)
Type "help" for help.
bar_development=# \d foo
Table "public.foo"
Column | Type | Modifiers
------------+-----------------------------+-----------
id | character varying | not null
name | character varying | not null
created_at | timestamp without time zone | not null
updated_at | timestamp without time zone | not null
Indexes:
"foo_pkey" PRIMARY KEY, btree (id)
我最终得到一个带有主键索引的'not null'字符串列。
更多地使用id
以外的列名。
编辑(2015年2月26日):在生成schema.rb
文件时,rails中似乎存在错误。它不会记录自定义主键状态,您需要进入并编辑它以将id: :string
选项添加到create_table
调用。
即
create_table "foo", id: :string, force: :cascade do |t|
t.string "name", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
糟糕的部分:每次迁移都会撤消该更改。你必须密切关注文件内容(或写一个测试:))。
该错误已在PR 18228中修复,并于2015年1月3日合并到rails:master。