【Rails】ユーザーページのURLをユーザーネームにする（twitter.com/hanamichi10みたいにする）

#【結論】

##ルーティング
```routes.rb
get '/mypage' => 'users#mypage'
get '/:username' => 'users#show'
get '/:username/edit' => 'users#edit'
patch '/:username' => 'users#update'
```

##リンクの作り方

```.erb
<div><%= link_to "#{user.username}のユーザーページ", "/#{user.username}" %></div>

<div><%= link_to 'マイページ', "/#{current_user.username}" %></div>

<div><%= link_to "プロフィール編集", "/#{current_user.username}/edit" %></div>
```

こんな感じ。
現状どうで、どんなことしたくて、どうやったか
の順番に述べます。誰かの役に立てることを願って。

#【現状】

[【Rails】Deviseを使ってユーザーページ/マイページを作る。プロフィール編集機能も実装する。](https://qiita.com/Jumpei_Sogawa/items/f3f2a3866b20028b49e9)
を参照してください。

##テーブル

- Userテーブル

カラム： email, password, username


##ルーティング
```routes.rb
get '/mypage' => 'users#mypage'
resources :users, only: [:show, :edit, :update]
```

##コントローラー

```users_controller.rb
before_action :authenticate_user!, only: [:mypage, :edit, :update]
before_action :set_user, only: [:show, :edit, :update]

def mypage
  redirect_to user_path(current_user)
end

def show
end

def edit
  unless @user == current_user
    redirect_to user_path(@user)
  end
end

def update
  if current_user.update(user_params)
    redirect_to user_path(current_user)
  else
    redirect_to edit_user_path(current_user)
  end
end

private

  def set_user
    @user = User.find([:id])
  end

  def user_params
    params.fetch(:user, {}).permit(:username)
  end
```

```.erb:users/show.html.erb
<% if user_signed_in? && @user == current_user %>
  <h1>マイページ</h1>
<% else %>
  <h1>ユーザーページ</h1>
<% end %>

<h1><%= @user.username %></h1>

<% if user_signed_in? && @user == current_user %>
  <%= link_to "プロフィール編集", edit_user_path(current_user) %>
<% else %>
```


#【】やりたいこと
ユーザーページを表示するには、現状`appname.com/users/1`にアクセスする仕組みになっている。
これを、`appname.com/hanamichi10`のように、`appname.com/ユーザーネーム`にアクセスして表示できるようにしたい。
twitter.comとかinstagram.comみたいに.

#【手順】
##ルーティング
```routes.rb
get '/mypage' => 'users#mypage'
get '/:username' => 'users#show'
get '/:username/edit' => 'users#edit'
patch '/:username' => 'users#update'
```

ここが重要。
まずはルーティングを変更する。
urlのparamsを:usernameで受け取る仕様にした。

自分のアプリケーションに追加で実装する場合は、書く位置にも注意。
これらをこの順番で一番下に書くことをおすすめする。
一番下に書かないと、他の全てのurlは`get '/:username'`として処理されてしまう。

##コントローラー
ルーティングの変更に伴ってパスが変わる。

```users_controller.rb
def mypage
-   redirect_to user_path(current_user)
+   redirect_to "/#{current_user.username}"
end

def show
end

def edit
  unless @user == current_user
-     redirect_to user_path(@user)
+     redirect_to "/#{@user.username}"
  end
end

def update
  if current_user.update(user_params)
-     redirect_to user_path(current_user)
+     redirect_to "/#{current_user.username}"
  else
-     redirect_to edit_user_path(current_user)
+     redirect_to "/#{current_user.username}/edit"
  end
end

private

  def set_user
-     @user = User.find([:id])
+     @user = User.find_by(username: params[:username])
  end

  def user_params
    params.fetch(:user, {}).permit(:username)
  end
```

##ビュー

- マイページへのリンク

```.erb
<div><%= link_to 'マイページ', "/#{current_user.username}" %></div>
```

- 他人のユーザーページへのリンク

```.erb
<div><%= link_to "#{user.username}のユーザーページ", "/#{user.username}" %></div>
```

- プロフィール編集

```users/show.html.erb
<div><%= link_to "プロフィール編集", "/#{current_user.username}/edit" %></div>
```

- プロフィール編集ページ

```.erb:users/edit.html.erb
<h1>プロフィール編集</h1>

<%= form_with(model: @user, url: "/#{@user.username}") do |form| %>
  <div>username<%= form.text_field :username %></div>
  <div><%= form.submit "保存" %></div>
<% end %>
```