Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
8
Help us understand the problem. What is going on with this article?

More than 5 years have passed since last update.

@prinum

railsモデルを削除して新しくmodelを追加したらIDが飛ばされることなく削除したモデルのIDが設定されてしまった。

Category has_many goodsのような関連のデータでCategoryモデルを削除し、新規に作成した場合、削除したIDの次の数値がIDとなるのが期待される挙動です。(例 ID=23のモデルを削除したら次に作成されるモデルのIDは24)

しかし特定の状況下ではそうならずに削除したIDが新規に作成したモデルに割り振られる事があるようです。(例 ID=23のモデルを削除したら次に作成されるモデルのIDに23が割り振られる)

こうなると思わぬ関連付けされてしまうので困ります。

> Category.find(23).destroy
  Category Load (0.7ms)  SELECT `categories`.* FROM `categories` WHERE `categories`.`id` = 23 LIMIT 1
   (0.1ms)  BEGIN
  SQL (0.3ms)  DELETE FROM `categories` WHERE `categories`.`id` = 23

下に自分が起きたとき原因だろうと思われるところを上げてみます。

  1. railsはmysqlを使う際InnoDBをデフォルトで使う
    Ruby on Rails : migration 機能リファレンス

    なお、バックエンドデータベースとして MySQL を使用している場合、:options を指定しないと "ENGINE=InnoDB" がデフォルトで指定されます。

  2. mysqlのInnoDBは外部key制約で参照されているtableのデータを削除するときはTRUNCATEが使用される。
    12.2.9. TRUNCATE 構文

もしテーブルを参照する外部キー制約があれば、InnoDB テーブルに対しては、TRUNCATE TABLE が DELETE にマップされ、そうでなければ、高速切断(テーブルのドロップと再作成)が利用されます。外部キー制約の有無に関わらず、AUTO_INCREMENT カウンタが TRUNCATE TABLE によってリセットされます。

  1. テーブルでTRUNCATEを使用するとauto incrementがリセットされる。

メッチャ役に立つauto_incrementの話のスライド21~23ページ目を参考にした。

21. テーブルをTRUNCATEするとどうなる?(シーケンスが12まで振られてる状態で)TRUNCATE TABLE tbl;INSERT INTOtbl(user_name)VALUES(‘userXX’);
22. シーケンスが巻き戻った
23. DELETEでは巻き戻らないが、 TRUNCATEだと巻き戻る

上記の3つの条件が同時に起こっているとオートインクリメントの挙動が期待されていないものになるようです。

対策としてはrailsのhas_manyにはdependent オプションがあるのでそれを設定しとくべきだと思います。
設定すると親モデルを削除した際に子モデルも同時に削除されるというものです。

railsでhas_manyで関連したモデルのデータを一気に消すとき

8
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
8
Help us understand the problem. What is going on with this article?