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ごとに連番になります。