rails で /users/:id ではなく /:username な routing にする方法
rails で普通に scaffold すると id が URL に入って example.com/users/:id
となる。
これを twitter.com/myname
とか github.com/yourname
みたいにしたい時がある。
実現には 2 通りの方法があると思われる。
to_param を使う方法
activerecord に to_param というメソッドがあって、これを使うと URL の :id の部分に id 以外を指定できるようになる。
user.rb
class User < ActiveRecord::Base
validates_presence_of :username
validates_uniqueness_of :username, case_sensitive: false
def to_param
username
end
end
users_controller.rb
class UsersController < ApplicationController
def show
@user = User.find_by(username: params[:id])
end
end
routes.rb
Rails.application.routes.draw do
resources :users, path: '/', only: [:show, :edit, :update, :destroy]
end
$ rake routes
Prefix Verb URI Pattern Controller#Action
edit_user GET /:id/edit(.:format) users#edit
user GET /:id(.:format) users#show
PATCH /:id(.:format) users#update
PUT /:id(.:format) users#update
DELETE /:id(.:format) users#destroy
routing で param を設定する方法
User クラスに to_param を定義せずに、 routes.rb で設定する方法。
params[:username]
というふうに渡ってくるので、こちらの方が素直な気がして個人的にはこちらを使いたい。
users_controller.rb
class UsersController < ApplicationController
def show
@user = User.find_by(username: params[:username])
end
end
routes.rb
Rails.application.routes.draw do
resources :users, param: :username, path: '/', only: [:show, :edit, :update, :destroy]
end
$ rake routes
Prefix Verb URI Pattern Controller#Action
edit_user GET /:username/edit(.:format) users#edit
user GET /:username(.:format) users#show
PATCH /:username(.:format) users#update
PUT /:username(.:format) users#update
DELETE /:username(.:format) users#destroy