1
0

More than 1 year has passed since last update.

ユーザーのURLをmyapp.com/usernameとかmyapp.com/settingsみたいなナウい感じにしたい(Rails)

Last updated at Posted at 2021-10-17

やりたいこと

ユーザーのマイページやアカウント設定ページのルーティングをしたいです。
普通にRailsのresourcesメソッドに任せてしまうと、my_app.com/users/:idてな具合になってしまいます。

でも、ナウいQiitaとかnoteとかだとこんな感じになっています。

https://qiita.com/kakudaisuke
https://qiita.com/settings/account

https://note.com/kakudaisuke
https://note.com/settings/account

シンプルでかっこいいじゃないですか!
僕のアプリもこうしたい!

実装してみて、簡単にできたものの、細かいところの調整がやや面倒だったのでメモを。

環境

ruby 2.7.2
Rails 6.1.4.1

実装!

routes

config/routes.rb
Rails.application.routes.draw do
  root 'posts#index'
  #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  # users
  devise_for :users,
             only: %i[session password registration],
             controllers: { sessions: 'users/sessions',
                            password: 'users/passwords',
                            registrations: 'users/registrations' }

  get '/users', to: 'users#index'
  get '/settings', to: 'users#edit'
  resources :users, param: :account_name, only: %i[show new create update destroy], path: '/'
end

(ユーザーに関わる部分なので、なんとなくdeviseのルーティングも併せて載せておきましたが、今回の実装とは全く関係ないので無視で。)

resourcesメソッドのparampathというオプションを駆使すると簡単にやりたいことは大体できてしまいます。

いくつか注意点があります。

  • indexresoucesに含めてしまうと、ルートmyapp.com/がユーザー一覧になってしまうんですよね。ルートpathは別に設定したいので分けました。

  • これ、順番が大事で、resources :usersを一番最後に書かないと、/posts/usersなどもaccount_nameだと判断されてしまいます。予期していないルーティングがされ「postsなんてユーザーいないぞ」とエラーに。

  • それでも例えばpostsなんていうアカウント名のユーザーがいたら、やはり、マイページではなく、posts一覧にルーティングしてしまいます。そこで、今回はモデルのバリデーションで使われたくない名前を定義してブロックしました↓。

app/models/user.rb
reserved_words = %w(posts users my_app)
validates :account_name, exclusion: { in: reserved_words }

Model

param: :account_nameを有効にするには、モデル側でパラメーターにidじゃないのを使うよーと宣言してあげないといけません。

user/rb
def to_param
  account_name
end

ドキュメント→https://railsdoc.com/page/to_param

Views

こんな感じで設定してあげます。

<%= link_to User.model_name.human, '/users' %>

<%= link_to 'アカウント設定', '/settings' %>

<%= link_to 'マイページ', user_path(current_user) %>

<%#= postのユーザー名からユーザーページへのリンク %>
<%= link_to(post.user.account_name, "/#{post.user.account_name}") %>

最後に

これでとりま自分がやりたいことは実現できました!
ただ、もっとなんかスマートな方法がある気もしています。。

何かご指摘などあればバシバシよろしくお願いします。

1
0
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
1
0