質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

2回答

831閲覧

Railsでauto_incrementのidを挿入する際、特定のテーブルに存在しないidを挿入したい

kuuritar

総合スコア38

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2018/12/06 12:02

以前の質問。
https://teratail.com/questions/157540
https://teratail.com/questions/162431

現状以下のようなテーブルがあります。

article id: integer title: string deleted_article id: integer article_id: integer title: string

articleを削除後、deleted_articleに情報を退避する感じです。

ここで上記一つ目の質問に書いてあるid再利用がarticleテーブルで起きてしまうため以下のような状況になってしまいます。

articleテーブル

idtitle
3title3
4title4
5title5
1title6

deleted_articleテーブル

idarticle_idtitle
11title1
22title2

ここでdeleted_articleのarticle_idはuniqueなので、title: "title6"の記事が削除できなくなっています。

ここでアプリケーション(Rails)側でdeleted_articlesのarticle_idに存在しないidのみをarticlesに挿入したいのですが、以下のような実装はどう思いますか?
(rollbackが起きるとauto incrementがプラスされるようなのでそれを利用しています。)

ruby

1loop do 2 begin 3 Article.transaction do 4 article = Article.create!(title: ’test’) 5 raise ActiveRecord::Rollback if DeletedArticle.exists?(article_id: article.id) 6 break 7 end 8 rescue 9 next 10 end 11end

また、もし他に良い案があれば教えてください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

そもそもなぜ ID: 1 title6 というデータが作られているのでしょうか
Database の auto_increment 任せなら ID: 6 title6 が作られ ID: 1,2 は歯抜けのままだと思うのです
一番良いのは、その変なデータが作られている場所の修正や、 もし auto_increment 設定のミスならそれを直すとかの根本解決だと思います

とはいえ誤魔化さないといけない or 誤魔化せば良い程度の話で記載された処理を改善するなら以下でしょうか
auto increment -> rollback だとID状況によっては最悪何十何百回と繰り返すことになるので、最大値を指定する感じです

ruby

1loop do 2 begin 3 Article.transaction do 4 max_id = [DeletedArticle.maximum(:article_id), Article.maximum(:id)].max 5 Article.create!(id: max_id + 1, title: ’test’) 6 end 7 rescue 8 next 9 end 10end

投稿2018/12/13 02:46

Ighrs

総合スコア656

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kuuritar

2018/12/13 03:07

ありがとうございます。 確かに最大値の設定は必要そうですね。 idが戻る理由ですが、先頭に置いたリンクに詳細を書いていますが、mysqlの仕様で、DB再起動や最適化等により起こるようです。
guest

0

論理削除をしたいだけなら、articleモデルにstatusカラムをつけておいて、削除操作した場合はstatusdeletedにするなどの設計が良いのではないでしょうか?

投稿2018/12/06 14:25

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kuuritar

2018/12/06 14:27

論理削除はやりたくなく、あくまでバックアップ目的で保存したいだけです。 article自体は物理削除したいです。
退会済みユーザー

退会済みユーザー

2018/12/06 14:30

なるほど、kuzugrさんのサービスの全体像を把握できないので、あまり有益なアドバイスとならず申し訳ございません。ちなみにですが、なぜ論理削除ではなく上のような方法を取ろうと考えられているのですか?
kuuritar

2018/12/06 15:30

>なぜ論理削除ではなく上のような方法を取ろうと考えられているのですか? これは私が動かしているサービスではなく、私が手伝っているサービスですでに稼働中だからですね・・・ 設計を変える必要があるためです。
退会済みユーザー

退会済みユーザー

2018/12/07 01:31

なるほど、自分の好きなようにはできないためとういうことですね。 事情も知らず、お力になれず申し訳ございまでんでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問