1. ホーム
  2. ruby-on-rails

[解決済み] Railsが既に存在するidを自動で割り当てる件

2023-01-06 15:02:28

質問

このように新しいレコードを作成します。

truck = Truck.create(:name=>name, :user_id=>2)

私のデータベースには現在トラック用の数千のエンティティがありますが、そのうちのいくつかにidを割り当て、いくつかのidを利用可能な状態にしました。 そこで、何が起こっているかというと、rails は id = 150 でアイテムを作成し、それはうまく動作します。 しかし、その後、アイテムを作成してid = 151を割り当てようとすると、そのidはすでに存在する可能性があるため、このエラーが表示されます。

ActiveRecord::RecordNotUnique (PG::Error: ERROR: duplicate key value violates unique constraint "companies_pkey" DETAIL: Key (id)=(151) already exists.

そして次にアクションを実行すると、単にid 152が割り当てられ、その値がまだ取られていなければうまくいきます。 どうすればrailsにIDを割り当てる前にすでに存在するかどうかをチェックさせることができるでしょうか?

ありがとうございます!

EDIT

Truck idが重複しているものです。 ユーザーはすでに存在し、この場合、定数です。 実は、これは私が対処しなければならないレガシーな問題なのです。 1つのオプションは、テーブルを再作成して、railsがすべてのidを自動で割り当てるようにすることです。 しかし、Truckは他の多くのテーブルの外部キーであるため、これを行うための移行は非常に複雑になるでしょう。 Truck の下にすでに保存されている同じデータで、自動割り当て ID と既存のすべての関係を維持する新しいテーブルを rails に作成させる簡単な方法はありますか?

どのように解決するのですか?

RailsはおそらくPostgreSQLの組み込みシーケンスを使用しているのでしょう。シーケンスのアイデアは、一度しか使われないということです。

最も簡単な解決策は、以下のようなクエリで、company.idカラムのシーケンスをテーブル内の最も高い値に設定することです。

SELECT setval('company_id_seq', (SELECT max(id) FROM company));

シーケンス名 "company_id_seq" 、テーブル名 "company" 、カラム名 "id" から推測しています・・・正しいものに置き換えてください。シーケンス名を取得するには SELECT pg_get_serial_sequence('tablename', 'columname'); でシーケンス名を取得するか、テーブルの定義を見て \d tablename .

別の解決策としては、保存前に新しい行の会社 ID を手動で設定するために、会社クラスの save() メソッドをオーバーライドすることです。