【Rails】deviseでルーティングを作成した際の、いろんなエラーと記述ミス

# はじめに
Deviseを使って管理者機能を取り入れようとモデルを作成した際、ルーティングやフォルダの設定などを変更した後にモデルの名前を変更したくなりました。

変更する際にちょっとしたエラーが発生したり、どこを直せばいいか少し迷った点を記録しておこうと思います。

# 結論
モデルの名前変更の手順としては、以下のコマンドでモデルを削除してから新しく作成し直します。
```
$ rails d devise 削除したいモデル名
$ rails g devise 追加したいモデル名
```
このときに、ルーティングの記述もチェックして削除するのがポイントです…！
ルーティングが正しい記述になっていないとエラーが発生してしまうので、今回、私が遭遇したエラーについてご説明します。

## 最初にやったこと…モデルの削除
まずは、結論でお伝えしたコマンドを打ち込んでモデルの削除を行いました。
dはdestroyの意味になります。
```
$ rails d devise Customer
```
このとき、Devise用のコントローラやビューも作成していましたが、名前の変更が不要なファイルだったため削除したいのはモデルだけ。

ということで、これで解決！と思い、新しくモデルを作成する以下のコマンドでMemberモデルを作成することにしました。

## rails g deviseで作成されたルーティングを消していなかった
```
$ rails g devise Member
```
意気揚々とこのコマンドで新しいMemberモデルを作成しようとしたら、ターミナルに以下のようなエラーが表示されてしまいました…。
```
：
`const_get': uninitialized constant Customer

        Object.const_get(camel_cased_word)
              ^^^^^^^^^^ (NameError)
：
```
他にもURLなどいろいろ表示されたのですが、ここで消したはずのモデルCustomerが何か引っかかっている予感がします。

でも、モデルは削除したし…と思い、調べたところ、こちらの質問記事を見つけました。

https://qiita.com/xDOLLx96/questions/b7771a95818beed88dc0

そうでした、Deviseでモデルを作成したらルーティングにも追加されるのでした…！
私のroutes.rbファイルを確認してみると以下の内容を発見。

```ruby:config/routes.rb
# 顧客用(public)
  devise_for :customers, controllers: {
    registrations: "public/registrations",
    sessions: 'public/sessions'
  }
```
こちらの記述を削除した後、改めて「$ rails g devise Member」を行うとエラーも表示されず無事にモデルの作成が完了しました。

確かに、ルーティングを後で直そうと思い、削除する前にモデルを作成しようとしていました。
ルーティングは間違っていたり重複していたりすると、他の作業をする前に教えてくれるんですね。親切です…。

## scopeを書き間違えた際のエラー対処
また、ルーティングを整えている際に同じようなエラーが発生しました。

新しいコントローラを作成しようとした際に、ターミナルに先ほどと同じようなエラー表示がされてしまって作成できませんでした。

ついさっき経験済みなのでこれもルーティングか…と思い、ファイルを確認。
```ruby:config/routes.rb
#↓本当は「scope module: :shop do」と書かなければならない
  scope module:shop do
    get 'top' =>  'homes#top', as: 'top'

    get 'shops/unsubscribe' => 'shops#unsubscribe', as: 'confirm_unsubscribe_shop'
    get 'shops/withdraw' => 'shops#withdraw', as: 'withdraw_shop'
    get 'members/:member_id/pre_orders' => 'pre_orders#index', as: 'member_pre_orders'

    resources :shops, only: [:edit, :update]
    resources :members, only: [:show]
    resources :items
    resources :pre_orders, only: [:show, :index, :update]
  end
```
よく見るとscopeの書き方が間違っていて、「: 」が足りていませんでした。
凡ミスです…。

## ルーティングの名前が重複していた際のエラー対処
今度は、先ほどとは少し違ったエラー表示が出ました。
```
：
`add_route': Invalid route name, already in use: 'top'  (ArgumentError)
：
```
どうやら'top'は既に使われている、というメッセージのよう。
ここまで来たら慣れたものなので落ち着いてルーティングを確認します。

```ruby:config/routes.rb

  scope module: :admin do
    get 'top' =>  'homes#top', as: 'top'
  #　↑ここに「as: 'top'」があるのに
    resources :shops, only: [:show, :index, :edit, :update]
    resources :members, only: [:show, :index, :edit, :update]
  end


  devise_for :shop, controllers: {
    registrations: "shop/registrations",
    sessions: 'shop/sessions'
  }

  scope module: :shop do
    get 'top' =>  'homes#top', as: 'top'
  #　↑ここにも「as: 'top'」がある
    get 'shops/unsubscribe' => 'shops#unsubscribe', as: 'confirm_unsubscribe_shop'
    get 'shops/withdraw' => 'shops#withdraw', as: 'withdraw_shop'
    get 'members/:member_id/pre_orders' => 'pre_orders#index', as: 'member_pre_orders'

    resources :shops, only: [:edit, :update]
    resources :members, only: [:show]
    resources :items
    resources :pre_orders, only: [:show, :index, :update]
  end
```
「get 'top' =>  'homes#top', as: 'top'」を記述した場所が2か所ありました。
私としては、「scope」の中に入れていたので「shop_top」や「admin_top」になるだろうと思っていたのですが、よくよく考えてみたら「scope」はコントローラのフォルダの場所を指定するための記述です。

この場合、片方の「as: 'top'」の部分を違う内容に書き換えればエラーは解消されるのですが、そもそも、今回私が作りたかったルーティングには、「scope」ではなく「namespace」を使う必要がありました。
```ruby:config/routes.rb
  devise_for :admin, skip: [:registrations, :passwords], controllers: {
    sessions: 'admin/sessions'
  }

  #　↓namespaceに変更
  namespace :admin do
    get 'top' =>  'homes#top', as: 'top'

    resources :shops, only: [:show, :index, :edit, :update]
    resources :members, only: [:show, :index, :edit, :update]
  end

    devise_for :shop, controllers: {
    registrations: "shop/registrations",
    sessions: 'shop/sessions'
  }

  #　↓namespaceに変更
  namespace :shop do
    get 'top' =>  'homes#top', as: 'top'

    get 'shops/unsubscribe' => 'shops#unsubscribe', as: 'confirm_unsubscribe_shop'
    get 'shops/withdraw' => 'shops#withdraw', as: 'withdraw_shop'
    get 'members/:member_id/pre_orders' => 'pre_orders#index', as: 'member_pre_orders'

    resources :shops, only: [:edit, :update]
    resources :members, only: [:show]
    resources :items
    resources :pre_orders, only: [:show, :index, :update]
  end
```
これでエラー表示もされず、ルーティングの設定は完了です。
なんだかまだ間違っている部分が出てきそうな気もしますが、そちらは追々修正していくことにしましょう。
  
# おわりに
エラーに遭遇したことで、ルーティングの記述のルールなどが少しずつ分かってきました。
ルーティングは記述の順番によっても上手くページが表示されなくなってしまうこともありますし、丁寧に確認する必要がありますね。

修正したり確認する際にも分かりやすいように、記述の整理整頓も心掛けていきたいです。