データベースの慣例では、自動インクリメントの主キーを使用するので、レールとはあまり関係がありません。
新しいテーブルの場合、railsがこの規則を使用しないようにするには、id列を自動的に作成しないように指示し、代わりに自分で作成する必要があります。
# example of creating a users table
create_table :users, id: false do |t|
t.integer :id
# other column definitions
end
add_index :users, [:id], unique: true, name: 'index_id_on_users'
次に、モデルで、レコードを作成する前にこれを明示的に設定する必要があります。
class User < ActiveRecord::Base
before_create :set_id
def set_id
loop do
self.id = rand(1<<32)
break unless User.exists?(self.id)
end
end
end
ループは、一意のキーを取得することを確認しているだけです。そうしないと、db制約によってエラーが発生します。競合状態はまだありますが、衝突が心配な場合は、UUIDやSHAなどを使用するよりも多くなります。
非整数キーの問題については、私自身は問題に遭遇したことがなく、UUIDキーとSHAキーの両方を使用したほか、id列ではない主キーを使用したことがあります。これにはもう少し構成が必要です。
現在のモデルに関しては、すべてのIDから自動インクリメントを削除する必要があります。そうしないと、データベースはユーザーからの指示をすべて無視するはずです。これは明らかに、idで列変更の移行を発行するだけで実行できます。
change_column :users, :id, :integer
ここでの注意点は、db / schema.rbが変更を反映しないため、db:schema:loadが適切なデータベースを生成しないことです。ただし、とにかくデータベースをロードするためにそのrakeタスクを使用したことはありません。db:migrateを使用するだけで、すべて問題ありません。
そしていつものように、このようなコマンドを実行する前に、必ずDBをバックアップしてください。開発環境のsqlite3で実行したところ、問題なく動作したようです。
アップデート#1
URLだけが関係している場合の代替ルートは、IDの代わりにスラッグを使用することです。少しの構成といくつかの新しい列でこれを処理するいくつかの宝石があります。基本的には、URLパラメータとして列を使用するという考え方です。したがって、/ resources / 1を出力する代わりにURLヘルパーを使用すると、/ resources/some-url-friendly-slugが出力されます。これは、UUIDやSHAのような不可解なものでも、SEOに適したものでもかまいません。モデルにスラッギングできるものがあるかどうかによって異なります。たとえば、それがproduct_pathであり、製品にタイトルが付いている場合、スラッグは製品タイトルのURLに適したバージョンであり、SEOに最適です。