railsのroutesのid以外にする方法
railsはdefaultのresourcesは:id
になっています。
config/routes.rb
resources :users
URIのパターンです。
Prefix Verb URI Pattern Controller#Action new_user GET /users/new(.:format) users#new edit_user GET /users/:id/edit(.:format) users#edit user GET /users/:id(.:format) users#show PATCH /users/:id(.:format) users#update PUT /users/:id(.:format) users#update DELETE /users/:id(.:format) users#destroy
ただ、id以外にしたい場合があります。
routesにparamをつけてid以外に変更する
その場合はparams
を付け足せばいいです。
config/routes.rb
resources :users, param: :name
users GET /users(.:format) users#index POST /users(.:format) users#create new_user GET /users/new(.:format) users#new edit_user GET /users/:name/edit(.:format) users#edit user GET /users/:name(.:format) users#show PATCH /users/:name(.:format) users#update PUT /users/:name(.:format) users#update DELETE /users/:name(.:format) users#destroy
linkを貼る場合に楽をする
そして、この時のlinkを貼る場合にdefaultでnameにしたい場合があります。
@user = User.first user_path(@user)
通常だと、この場合はidになるので、/users/1
になります。
これをnameに変更します。
model/User.rb
def to_param name end
これで/users/foo
になります。
注意点
ただし、これをやる場合はnameがuniqにしておけないとバグの温床になります。 例えば、nameにfooが二人いた場合です。 だいたいcontrollerに書くのは下記のようなコードだと思います。
def show @user = User.find_by(params[:name]) ... end
find_byは最初の一つしか取得しないので、二つ以上あると予期せぬ挙動になります。
def find_by(arg, *args) where(arg, *args).take rescue ::RangeError nil end
そのため、DB/モデルにuniq制約
をつけるのを忘れないようにしましょう。
以上です。