【rails】userとadmin画面の作成手順について②

こんにちは、たにーです。

今回は、userとadminにdevise以外のモデルとコントローラーを作成していきます。

前回の手順に作成したものを元に進めています。まだの方は、こちらからどうぞ。

https://qiita.com/tani__san929/items/373d29c4bf092d474d5f


#目標

usesとadminの両方に商品一覧を表示させることを目標とします。
機能としては、こうなる想定。

- user =>  商品一覧画面、商品詳細画面
- admin => 商品一覧画面、商品詳細画面、商品編集画面

#まずは、モデル作成

前回は、userとadminで別々にモデルを作成しましたが、
今回は同じモデルを使いますので、分ける必要はありません。

モデル名は、「item」にします。
こんな感じで設定します。

|カラム | データ型 |
|:-:|:-:|
| name  | string |
| description  | text  |
| price_without_tax  | integer  |
| image_id  | string  |
| sales_status  | boolean  |

ターミナルで作成します。

```rb:terminal
$rails g model item
```

モデルファイルが作成されるので移動します。
ここに先程の設定したカラム名等を追記します。

```rb:db/migrate/create_items.rb
class CreateItems < ActiveRecord::Migration[5.2]
  def change
    create_table :items do |t|
      
      t.timestamps
    end
  end
end
```

追記後はこんな感じになります。

```rb:db/migrate/create_items.rb
class CreateItems < ActiveRecord::Migration[5.2]
  def change
    create_table :items do |t|
      t.string :name, null: false
      t.text :description, null: false
      t.integer :price_excluding_tax, null: false
      t.string :image_id
      t.boolean :sales_status, default: true, null: false

      t.timestamps
    end
  end
end
```

追記したらDBに反映しましょう。

```rb:terminal
$rails db:migrate
```

無事出来たら、schema.rbに反映されます。

```rb:db/migrate/schema.rb
        #省略

create_table "items", force: :cascade do |t|
    t.string "name", null: false
    t.text "description", null: false
    t.integer "price_excluding_tax", null: false
    t.string "image_id"
    t.boolean "sales_status", default: true, null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

       #省略
```

#itemsコントローラーの作成

ここは、userとadminそれぞれのコントローラーが必要になります。
一度、過去に作成した、それぞれのコントローラーを見てみると、、、、

```rb:app/controllers/users/confirmations_controller.rb
class Users::ConfirmationsController < Devise::ConfirmationsController
```

```rb:app/controllers/admins/confirmations_controller.rb
class Admins::ConfirmationsController < Devise::ConfirmationsController
```

classの部分をよくみると、
Users:: Admins:: いつもと異なっています。これが頭にあることで、
usersのコントローラーなのか、adminsのコントローラーなのかを識別しています。

通常はこんな感じです。

```rb:app/controllers/items_controller.rb
class ItemsController < ApplicationController
```

なので、ターミナル時点で頭に付くようにコマンドを打ちます。
書き方は下記の通り。同時にviewも作成しちゃいましょう。

```rb:terminal
$rails g controller users::items index show
```
コントローラー名の前につけるだけ。
結果として、usersのディレクトリに配下され、記述も下記の通りになります。

```rb/app/controllers/users/items_controller.rb
class User::ItemsController < ApplicationController
end
```

なので、 adminも同様に実行します。（省略します。）

#ルーティグの設定をします。

先ほど、コントローラーと同時にビューを作成したので、
下記のように追記されていると思います。

```rb:routes.rb
Rails.application.routes.draw do
  namespace :users do
    get 'items/index'
    get 'items/show'
  end
  
  namespace :admins do
    get 'items/index'
    get 'items/show'
    get 'items/edit'
  end
```

**namespaceを使うと指定したルーティングの配下にルーティングを設定することができます。**
先程のコマンドでusers:: や　admins:: 付けて実行したため、自動的にusers/adminsの配下として追記されています。

これだど他のコントローラーを作成し、htmlファイルを追加するたびに行だけが増えていってしますので修正します。
resourcesを使いましょう。

```rb:routes.rb
Rails.application.routes.draw do
  namespace :users do
    resources :items, only:[:index, :show]
  end
  
  namespace :admins do
    resources :items, only:[:index, :show, :edit, :new]
  end
```

これでitems周りの準備完了です。
後は、コントローラーにアクション定義やビューを書いていけば問題なく表示できると思います。

この流れでおそらく他のモデル、コントローラー、ルーティング設定をしていけば上手くいと思います。

#URLからusersを消したい場合

仮の想定として、URLからusersを表示したくないとします。
そんな事ができるのか？と思いながらも、方法を探して見ました。

結論としては、**「scope module: do」**を使います。
railsガイドにわかりやすく書いてありましたので、それをもとに実装していきます。

```rb:routes.rb
  scope module: :users do
    resources :items, only:[:index, :show]
  end
```

ルーティングを確認しましょう。

```title:terminal
         Prefix Verb   URI Pattern                      Controller#Action
          items GET    /items(.:format)                 users/items#index
          item  GET    /items/:id(.:format)             users/items#show
   admins_items GET    /admins/items(.:format)          admins/items#index
new_admins_item GET    /admins/items/new(.:format)      admins/items#new
```

usersの方だけが、URLから消えています。完了です！！！！

また、明日にでもnamespaceやspace moduleについてまとめた記事を書こうと思います。

以上、たにーでした。

#参考文献

https://diveintocode.jp/blogs/Technology/Routing3

https://pikawaka.com/rails/resources

https://railsguides.jp/routing.html