0

これは、私が以前に尋ねた質問に基づいたものです(運がない場合)。

文字列を主キーとして使用しているモデルがあります。

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

私はpostgres9.1.3をローカルで実行しています(そしてHerokuは9.1.4にあります)。私はRails3.2.3を使用しています。

私の質問は次のとおりです。

  • ここで何が起こっているのか分かりますか?
  • 主キーとしてemployment_idを使用しているのは正しいと思いますか?
  • 'id'フィールドを削除すると役に立ちますか?
  • 他に推奨するベストプラクティスはありますか?

ご協力いただきありがとうございます!

デレク。

編集:

要求に応じて移行ファイルを追加します。

class CreateEmployees < ActiveRecord::Migration
  def change
    create_table :employees do |t|
      t.string :employment_id, :unique => true
      etc...
    end
  end
end

編集

これを指摘する人はほとんどいませんが、本当の答えは「できるからといって、そうすべきだという意味ではありません」ということは明らかです。

4

2 に答える 2

1

この投稿によると、それは問題を解決するはずです:

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
于 2012-07-20T14:44:20.273 に答える
1

Rails4.2.0とPostgresのアップデートが誰かを助ける場合に備えて...

オプションにaid: :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)

最終的に、主キーインデックスを持つ「nullではない」文字列列になります。

以外の列名を使用するidと、より複雑になります。

編集(2015年2月26日):schema.rbファイルを生成するときにレールにバグがあるようです。カスタム主キーの状態は記録されません。呼び出しに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

くだらない部分:移行を行うたびに、その変更は元に戻されます。ファイルの内容を注意深く監視する必要があります(またはテストを作成します:))。

バグはPR18228で修正され、2015年1月3日にrails:masterにマージされました。

于 2015-02-25T05:59:51.767 に答える