LoginSignup
6
4

More than 5 years have passed since last update.

Rails: 階層構造のリソースで子リソースのIDを連番にしたい

Posted at

Railsではルーティングでリソースを階層構造にできますが、子リソースのIDは子リソース全体の連番になってしまい、URLにしたときかっこ良くないことがあります。

こうではなく
/questions/3 ... 質問のURL
/questions/3/answers/100 ... 質問3への回答の詳細URL
/questions/3/answers/123 ... 同上
/questions/3/answers/145 ... 同上
こうしたい
/questions/3 ... 質問のURL
/questions/3/answers/1 ... 質問3への回答の詳細URL
/questions/3/answers/2 ... 同上
/questions/3/answers/3 ... 同上

いろいろ調べましたが、sequencedというgemで手っ取り早く解決できるようです。

sequencedのインストール

Gemfile
gem 'sequenced'
$ bundle install

モデルを作る

連番をつけたいモデルにsequential_idカラムを追加し、DBをマイグレーションします。例えば、Questionに複数のAnswerがつく場合、Answerにsequential_idを追加します。

$ rails generate model Question
$ rails generate model Answer question:references sequential_id:integer
db/migrate/20160903082623_create_answers.rb
class CreateAnswers < ActiveRecord::Migration
  def change
    create_table :answers do |t|
      # null: falseを追加
      t.references :question, index: true, foreign_key: true, null: false

      # null: falseを追加
      t.integer :sequential_id, null: false

      t.timestamps null: false
    end
    # 複合ユニーク制約
    add_index :answers, [:question_id, :sequential_id], unique: true
  end
end
$ rake db:migrate

Answerモデルにacts_as_sequencedを追加します。

app/models/answer.rb
class Answer < ActiveRecord::Base
  belongs_to :question

  # この行を追加
  acts_as_sequenced scope: :question_id
end

これで、AnswerはQuestionごとに連番になります。

参考: Rails: sequencedでネストしたリソースのIDを連番にする

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4