Before Rails Tutorial ポケモン図鑑をつくろう

# はじめに
本投稿は講義資料であり、Rubyの基礎は理解しているが、rails tutorialで躓く読者を対象としています。

## 今回作るものの完成図
### ポケモン図鑑一覧ページ
![スクリーンショット 2023-04-19 12.41.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/e7bcb622-f13e-8c0e-9b72-4825d0b063a5.png)

### ポケモン詳細ページ
![スクリーンショット 2023-04-19 12.42.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/3a89ceaa-869e-5ab4-55ac-f4fad2d96229.png)

### ポケモン登録ページ
![スクリーンショット 2023-04-19 12.42.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/90f67feb-9ab0-3689-917a-5b5f7d53a8c7.png)


今回はポケモンずかんの開発を進める中で、webサービス開発の基礎知識を学んでいきます。

講義は基本的にテキスト通りに進めますが、
講師が実際に現場で使われている経験や知識を交えながら進行していきます。
区切りの良いところで止めて、教室を見回るので詰まっている方は気軽に呼び止めてください。

## 目次
[1章:　環境構築](https://qiita.com/earth660/items/a51874eba618e2aa5ce6)
[2章: ポケモン図鑑をつくろう](https://qiita.com/earth660/items/6773e8b59cc24c772244) ◀ いまここ
[3章: ポケモン図鑑 課題](https://qiita.com/earth660/items/94fcec3943f5004090d9)

***

本テキストに沿ってRailsアプリケーションを開発していきます。
その前に、Railsで開発する上で必要な知識を解説していきます。

# Webページが表示される仕組み
https://pikawaka.com/rails/curriculums-rails-basic-routing-controller-view

https://pikawaka.com/rails/mvc




***
# Webフレームワーク -MVCとは 
MVCに関しては後でも説明するので、いまはふわっとした理解で大丈夫です。


::: note info 
**Modelは、データベースとのやりとりを担う**
**Viewは、表示関連全般を担う**
**Controllerは、橋渡しの役割を担う**
:::


![MVC-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/3ab78069-8c5d-2dcb-e1eb-6fb4d4fa07ba.png)

例）具体的に/usersのindexページをブラウザで開くという操作を行う時

1. ブラウザから `/users`へのリクエストをRailsサーバーに送信する
2. `router` によって、`/users` は `Users controller`の`index`アクションを呼び出す
3. `index` アクションから、`User Model`が呼び出される
4. `User Model` は `DataBase` からデータを取り出す
5. 取り出したデータを、`Controller`に返す
6. 受け取ったデータを`@users`に保存し、 View (indexアクションなので index.html.erb) に渡す。
7. ERBを実行し、`@users`のデータを含んだ HTMLを生成し、`Controller`へ返す
8. `Controller`は、受け取ったHTMLをブラウザにわたす

今後もModel View Controller を構築していくので、適宜図を見返してください。


# 下準備

## 1. CSSフレームワークを導入してみよう
単にプログラムを書いても、味気ないデザイン（というかデザインがない状態）なので、CSSフレームワークを導入してそれっぽくしてみましょう。
今回はBulmaというCSSフレームワークを使用します。
[CSSとは？](https://saruwakakun.com/html-css/basic/css)
[Bulma　公式サイト](https://bulma.io/)

### erbファイルに追記する

`app/views/layouts/application.html.erb`のコードをすべて削除して下記のコードを丸々コピー&ペーストしてください。

::: note info

goorm内左側から
①**pokemon_zukan**フォルダをクリック
②**app**フォルダをクリック
③**layouts**フォルダをクリック
④**application.html.erb**をクリックすると中央にエディタ（コードを書く場所）が出るので、ここで編集してください。
**編集後は必ず保存をしましょう。**
![スクリーンショット 2022-06-28 13.55.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/06debe3a-0582-8fa4-1e5b-c91c3e4f6ba4.png)

:::


```html:app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>PokemonZukan</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>
　　    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
     <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
     <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <%= yield %>
  </body>
</html>

```


## 2.Font Awesomeの導入
無料で使えるwebフォントアイコンを導入しましょう。


**webフォントアイコンとは**
> HTMLのタグや特有のクラス名を付与することで、簡単にWebサイト上にアイコンを表示できるサービス。
> フォントとしてアイコンを利用することができるので、CSSで簡単にサイズや色を変更できるため、使い勝手にも優れている。

` font-awesome-sass`というgemを使用するので、
Gemfileの2７行目
の`# gem 'image_processing', '~> 1.2'`の下に
`gem 'font-awesome-sass'`を追加しましょう。
```Gemfile:Gemfile(下記の１行を追記してください)
gem 'font-awesome-sass'
```


![スクリーンショット 2023-04-14 15.56.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/7414e72d-1c4a-702e-3f88-e6c22138bc0a.png)
追加したら`bundle install`をします。
```terminal:terminal
$ bundle install
```

::: note info


▶︎ run new ruby on Railsを実行したまま、コマンドを実行したい場合、
新しくターミナルを開く必要があります。
goorm内上部のWINDOW > New Terminal Window(一番上)をクリックすると起動します。
![スクリーンショット 2023-04-19 1.11.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/6aa2fb10-1bf4-9a7a-1a4b-55e002646fc8.png)

:::


<font color="green">Bundle complete! 18 Gemfile dependencies, 76 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.


と緑文字で表示されるとインストール完了です。

### stylesheetの編集
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f33333039322f63346663623263392d393634302d373533622d336462352d3432613937356430626436312e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/59146400-ab70-bcd4-e965-e27283762dae.png)

pokemon_zukanをクリック > appをクリック > assetsをクリック > stylesheetsをクリック > `application.css`を右クリックして`名前を変更`をクリックし
画像の様に`application.scss`に変更してください。
（現時点で、同じ階層にあるpokemons.scssが皆さんは無いと思いますが、気にしないでください。あとで作ります。）


名前変更した`application.scss`を開き、
◯行目に下の1行を追加します。
```scss:app/assets/stylesheets/application.scss
/*
 * This is a manifest file that'll be compiled into application.css, which will include all the files
 * listed below.
 *
 * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
 * vendor/assets/stylesheets directory can be referenced here using a relative path.
 *
 * You're free to add application-wide styles to this file and they'll appear at the bottom of the
 * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
 * files in this directory. Styles in this file should be added after the last require_* statement.
 * It is generally better to create a new file per style scope.
 *
 *= require_tree .
 *= require_self
 */

@import 'font-awesome'; // これを追加する
```


## 3.画像アップロードの準備
アプリケーションにポケモンの画像を投稿する機能を追加したいので、
Rails5.2より追加されたActive Strageという公式で公開されたファイルアップロード機能を使用します。
[Active Storageについての説明](https://pikawaka.com/rails/active_storage)

### ImageMagickを導入
ターミナルで下記のコマンドを**1行ずつ**実行してください。
(どのコマンドでかを書く)途中で`Do you want to continue? [Y/n]`と聞かれます。Yを入力してください。
```terminal:terminal（１行ずつ実行してください）
$ sudo apt-get update
$ sudo apt-get install libmagickwand-dev
$ sudo apt-get install imagemagick --fix-missing
```



### Active Strageのインストール
Active StrageをRailsアプリケーションに追加します。
ターミナルで下記のコマンド**1行ずつ実行してください。**
```terminal:terminal(1行ずつ実行してください)
$ rails active_storage:install
$ rails db:migrate
```

### Gemfileの編集
Gemfileの27,28行目あたり(先程追加した`gem 'font-awesome-sass'`の下)に下記を追加して、`bundle install`をしてください。
```Gemfile:Gemfile(下記の２行を追記してください)
gem 'mini_magick'
gem 'image_processing', '~> 1.2'
```

![スクリーンショット 2023-04-19 1.56.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/883fa7e3-77a3-9d66-a930-1462f01a8b94.png)




```terminal:terminal(ターミナルで実行してください)
$ bundle install
```
ここでも
<font color="green"> Bundle complete! (以下省略)

と表示されていたらOKです


::: note
新たにgemを入れたあとはサーバーを起動し直しましょう。
でないと、追加したgemが反映されません。

`▶ new run ruby on Rails`を実行してるターミナルでCtrl + C でサーバーを止めてから
もう一度`▶ new run ruby on Rails`を押してください

:::

## 3. protect_from_forgeryの追加
[RailsのCSRF対策について](https://qiita.com/eshow/items/915f8e8ad317aa8e49a6)
`app/controllers/application_controller.rb`の◯行目にprotect_from_forgeryを追記してください。
```ruby:app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
 protect_from_forgery # これを追加する
end
```


これで下準備は完了です。
次にページを作っていきます。

下準備をしたファイルの完成形を折りたたみで書く



# ページを作成する方法
### ポケモン図鑑一覧ページ
![スクリーンショット 2023-04-19 12.41.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/e7bcb622-f13e-8c0e-9b72-4825d0b063a5.png)

### ポケモン詳細ページ
![スクリーンショット 2023-04-19 12.42.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/3a89ceaa-869e-5ab4-55ac-f4fad2d96229.png)

### ポケモン登録ページ
![スクリーンショット 2023-04-19 12.42.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/90f67feb-9ab0-3689-917a-5b5f7d53a8c7.png)

ページを作成するにはcotrollerとviewが必要になります。
## Controller と View の作成

作成は基本的に **`generate`** コマンドを用います。
(gは generateコマンドの短縮形です)
gの後は、controller に続けて、コントローラーの名前(`複数形`)を書きます。
`rails g controller Pokemons index show new`
そのうしろ（引数といいます）に書いたもの(index,show,new)は、
同名のviewとアクションが自動生成されます。
(Viewは views/pokemons の中に、アクションは apppokemons_controller.rbの中に生成)

```terminal:tarminal
$ rails g controller Pokemons index show new
     create    app/controllers/pokemons_controller.rb
     route     get 'pokemons/index'
               get 'pokemons/show'
               get 'pokemons/new'
     create    app/views/pokemons
     create    app/views/pokemons/index.html.erb
     create    app/views/pokemons/show.html.erb
     create    app/views/pokemons/new.html.erb
```


先程のrails g ...コマンドでルーティングが生成されているので、確認してみましょう。
確認するには`rails routes`コマンドを実行します。

```terminal:terminal
$ rails routes #実行してしばらくすると下記ルーティングが出てきます
  Verb  URI                Pattern
  GET   /pokemons/index    pokemons#index
  GET   /pokemons/show     pokemons#show
  GET   /pokemons/new      pokemons#new
```

これは具体的には、　http://localhost:3000/pokemons/index
というURLに対するリクエスト<sub><a href="#1">1</a></sub>があれば、 **pokemons_controller** の**index アクション**を呼び出すというものでした。
今回indexアクションの中身が空なので、Model は呼び出されず、単に対応するView (index.html.erb) が実行されるだけです。(図の3,4,5の部分が素通りされます)

ルーティングがうまくいってみるか確認するために、試しにアクセスしてみましょう。
(サーバーを起動していない場合は▶new run ruby on Railsをクリックして起動してください)

https://[pokemon_zukan-[id(人によって文字列は異なります)]].run.goorm.site/の続きに
`pokemons/index`を追記します。



![スクリーンショット 2023-04-19 2.01.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/48bcfad3-6378-d0a6-126d-1313fd36a229.png)

このように表示されていることを確認してください
ここで準備したCSSフレームワークが適用されているか確認してください。
（画像と同じスタイルになっていたら正しく適用されています。）

::: note warn
imagesフォルダ内の画像（１０枚）をapp/assets/imagesフォルダ内に移動させてください。
フォルダごとではなく中にある画像１０枚を移動させてください。
:::


### デザインの変更
`pokemons.scss`を編集します。
<details open><summary>"▶"をクリックしてscssファイルを丸々コピー＆ペーストしてください</summary>


```scss:app/assets/stylesheets/pokemons.scss
// =====  Pokemon/show ===== //
.pokemon-name {
  background-color: #344e67;
  color: #f2f5ec;
  font-size: 25px;
  line-height: 65px;
}

.p-type {
  display:inline;
  font-size: 20px;
  margin: 3em;  
}

.p-description {
  background-color: #fff;
  color: #283b4f;
  font-size: 20px;
  line-height: 1.5;  
  padding: 50px;
}

.pokemon-card {
  background-color: #fff;
  display: table;
  padding: 20px;
}

.p-name {
  display: table-cell;
  vertical-align: middle;
}

.vertical-middle {
  display: inline-block;
  vertical-align: middle;
}

.p-edit {
  margin-top: 110px;
  
  a {
    font-size: 16px;
    display:inline;
    margin-top: 60px;
  }
}

.alert {
  background-color: #ffebe8;
  border: 2px solid #990000;
  color: #262626;
  font-weight: 850;
  text-align: center;
  padding: 12px;
}
```
</details>



#### Viewの変更
元々あるダミー文を変更してみましょう。
`app/views/pokemons/index.html.erb`にあるコードをすべて削除し、
下記を追記してください。
```erb:app/views/pokemons/index.html.erb
<h1 class="title has-text-centered">ポケモンいちらん</h1>
```


::: note
erb の中身がシンプルすぎて不思議な方もいらっしゃるかもしれません。
【気になって次にすすめない人向けの解説】
`app/views/layouts/application.html.erb`　を開いてください。
コード内の`= yield`の部分に、`index.html.erb`が移植されて HTML を生成しています。　
今はこの程度の理解で問題ありません。 
https://railstutorial.jp/ でより深く理解できます
:::


#### Controllerの変更

コントローラーの中にアクションが本当に作られているかも確認してみましょう。
app/controllers/pokemons_controller.rb を開いてみてください。

```ruby:app/controllers/pokemons_controller.rb
class PokemonsController < ApplicationController
  def index
  end

  def show
  end

  def new
  end
end
```

データベース内のデータを取り出すには、Controllerのアクション内で
Model を呼び出すと取りだすことができます。

```ruby:app/controllers/pokemons_controller.rb
class PokemonsController < ApplicationController
  def index
  end

  def show
    @pokemon = Pokemon.find(1) # これを追記
  end

  def new
  end
end
```

しかし、このまま`pokemons/show`にアクセスしても
**uninitialized constant PokemonsController::Pokemon**というエラーがでます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/d705fb4a-d8a8-de81-09c0-746230501f1a.png)

（Modelも、ポケモンの情報も作っていないからです）

ですので、次は`generate`コマンドを使用して、`Model`を作成していきます。

# 情報のやりとり(データベース) の使用方法
## Modelの作成
pokemonsテーブルには、
ポケモンの名前(**name**)
図鑑番号(**number**)
ポケモンのタイプ(**zokusei**)
ポケモンの説明(**description**)
ポケモンの画像(**image**)
を持たせていきます。


g の後は、model に続けて、Model名(`単数形`)、そして項目（**カラム**といいます）を書きます。
```terminal:コマンドプロンプト
> rails g model Pokemon name:string number:integer zokusei:string description:text image:attachment
      invoke  active_record
      create    db/migrate/20220426050238_create_pokemons.rb
      create    app/models/pokemon.rb
      invoke    test_unit
      create      test/models/pokemon_test.rb
      create      test/fixtures/pokemons.yml

```

作成・編集したマイグレーションファイルはターミナルで`rails db:migrate`を実行すると読み込まれ、データベースに反映されます。
`rails db:migrate`を実行しましょう。
```terminal:terminal
>  rails db:migrate
== 20220426050238 CreatePokemons: migrating ===================================
-- create_table(:pokemons)
   -> 0.0052s
== 20220426050238 CreatePokemons: migrated (0.0058s) ==========================
```

:::note info
db/migrate/（作成日時）_create_pokemons.rb　というファイルを見てみましょう。
開いてみると、下記のようなコードがあると思います。
```rb:[作成日付]_create_pokemons.rb
class CreatePokemons < ActiveRecord
  def change
    create_table :pokemons do |t|
      t.string :name
      t.integer :number
      t.string :zokusei
      t.text :description
      t.timestamps
    end
  end
end
```
上記は string型であるnameというカラム（他5つ）を持つ pokemons テーブルを作成せよという意味です。 change 意外に up down などもあります。詳細は下記サイトなどを参照ください
[【Rails入門】データベースを設定するrails db:migrateを説明！](https://www.sejuku.net/blog/14229)
:::

***

これでpokemonsテーブルが作成されました。

テーブルは作成したけども、ポケモンの情報はまだ何もいれてませんね。
初期データをいれるに`db:seed.rb`ファイルを使用します。
( seed = 種　という意味です )
大量のデータを入力するのは手間なのでseed.rbを作成していきます。
(そもそもブラウザからデータをいれる機能もまだ作っていません)


seed.rbを編集しましょう。

<details><summary>`▶`をクリックしてソースコードを開き、
丸々コピー＆ペーストしてください</summary>


```rb:db/seeds.rb
pokemon = Pokemon.create!(name: "フシギダネ",
						 zokusei: "くさ",
						 number: 1,
						 description: "うまれてから しばらくの あいだは せなかの タネから えいようを もらって おおきく そだつ。")
pokemon.image.attach(io: File.open(Rails.root.join('app/assets/images/hushigidane.png')),
                  filename: 'hushigidane.png')

pokemon = Pokemon.create!(name: "フシギソウ",
						 zokusei: "くさ",
						 number: 2,
						 description: "せなかの つぼみが ふくらみだすと あまい においが ただよいはじめる。たいりんの はなが さく まえぶれ。")
pokemon.image.attach(io: File.open(Rails.root.join('app/assets/images/hushigisou.png')),
                  filename: 'hushigisou.png')

pokemon = Pokemon.create!(name: "フシギバナ",
						 zokusei: "くさ",
						 number: 3,
						 description: "あめの ふった よくじつは せなかの はなの かおりが つよまる。かおりに さそわれ ポケモンが あつまる。")
pokemon.image.attach(io: File.open(Rails.root.join('app/assets/images/hushigibana.png')),
                  filename: 'hushigibana.png')


pokemon = Pokemon.create!(name: "ヒトカゲ",
						 zokusei: "ほのお",
						 number: 4,
						 description: "ヒトカゲの　ほのおの　しっぽは　いのちの　ともしび。　げんきなときは　ほのおも　ちからづよく　もえあがる。")
pokemon.image.attach(io: File.open(Rails.root.join('app/assets/images/hitokage.png')), filename:'hitokage.png')

pokemon = Pokemon.create!(name: "リザード",
						 zokusei: "ほのお",
						 number: 5,
						 description: "リザードが くらす いわやまを よなかに みあげると しっぽの ほのおが ほしのように みえる。")
pokemon.image.attach(io: File.open(Rails.root.join('app/assets/images/riza-do.png')), filename:'riza-do.png')

pokemon = Pokemon.create!(name: "リザードン",
						 zokusei: "ほのお",
						 number: 6,
						 description: "くるしい たたかいを けいけんした リザードンほど ほのおの おんどが たかくなると いわれている。
")
pokemon.image.attach(io: File.open(Rails.root.join('app/assets/images/riza-don.png')), filename:'riza-don.png')



pokemon = Pokemon.create!(name: "ゼニガメ",
						 zokusei: "みず",
						 number: 7,
						 description: "こうらに とじこもり みを まもる。 あいての すきを みのがさず みずを ふきだして はんげきする。")
pokemon.image.attach(io: File.open(Rails.root.join('app/assets/images/zenigame.png')),
                  filename: 'zenigame.png')

pokemon = Pokemon.create!(name: "カメール",
						 zokusei: "みず",
						 number: 8,
						 description: "いちまんねんの じゅみょうを もつと いわれている。ふさふさの しっぽは ながいきの シンボルとして にんき。")
pokemon.image.attach(io: File.open(Rails.root.join('app/assets/images/zenigame.png')),
                  filename: 'kame-ru.png')

pokemon = Pokemon.create!(name: "カメックス",
						 zokusei: "みず",
						 number: 9,
						 description: "こうらの ふんしゃこうの ねらいは せいかく。みずの だんがんを 50メートル はなれた あきかんに めいちゅうさせる ことが できるぞ。")
pokemon.image.attach(io: File.open(Rails.root.join('app/assets/images/kamekkusu.png')),
                  filename: 'kamekkusu.png')


pokemon = Pokemon.create!(name: "イーブイ",
						 zokusei: "ノーマル",
						 number: 133,
						 description: "しんかのとき すがたと のうりょくが かわることで きびしい かんきょうに たいおうする めずらしい ポケモン。")
pokemon.image.attach(io: File.open(Rails.root.join('app/assets/images/i-bui.png')),
                  filename: 'i-bui.png')
```
</details>


そしてデータの読み込みを`rails db:seed`で行います。
```terminal:コマンドプロンプト
> rails db:seed
```

データが保存されたかの確認は`rails c`でコンソールを起動すると確認できます。

```terminal:コマンドプロンプト
> rails c
unning via Spring preloader in process 6309
Loading development environment (Rails 6.0.3.2)
irb(main):001:0>
```
このような文字が表示されたらコンソールは起動されています。
`irb(main):001:0>`に下記のコマンドを入力していきます。 

```rb:(irb(main):001:0に以下のコマンドを入力して実行してください)
p = Pokemon.find(1)
```


フシギダネの情報がimage以外表示されていればOKです
![スクリーンショット 2023-04-19 12.17.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/8338856a-f5de-02e2-09da-8103ad9af4f2.png)





::: note
  コンソールから出る場合は**exit**を入力すると戻る事が出来ます。
:::

フシギダネの情報をページ上で表示させたいので、
`app/views/pokemons/show.html.erb`を下記のように編集しましょう。

```erb:app/views/pokemons/show.html.erb
<div class="pokemon-name">
  <div class="container">
    <p style="display: inline; padding-left: 40px;">
      NO.<%= @pokemon.number %>
      <%= @pokemon.name%>
    </p>
        
    <p class="p-type">
      <%= @pokemon.zokusei %>
    </p>
  </div>
</div>

<div class="columns">
      <div class="column is-4">
        <div class="pokemon-img">
        　　<%= image_tag @pokemon.image %>
        </div>
    　</div>
    
      <div class="column is-8">
        <div class="p-description">
          <%= @pokemon.description %>
        </div>
      </div>
    </div>
  </div>
</div>

```
https://pokemon-zukan-[ランダムな文字列].run.goorm.site/pokemons/show
にアクセスしてください。
フシギダネの情報が表示されたかと思います。
![スクリーンショット 2023-04-19 12.28.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/e7b08cc2-8a0b-ff57-376c-c15c879ee977.png)



# URLからパラメーターの取得
ポケモンのデータを取り出して表示するところまでうまくいきました！
すごい進歩です！

ただ、まだ不満点があります。
それは、 id:1 のポケモンのデータしか表示できていない点です。
理由は、Contoroller の show アクションをみると、
`@pokemon = Pokemon.find(1)`
となっているためです(id:1 のポケモンの情報しか見つけてきていない)

ここをidパラメーターが１以外も入力できるように変更するにはどうすればよいでしょうか。
`@pokemon = Pokemon.find(params[:id])`
とすることで、１以外のパラメーターを見つけてこれます。

```ruby:app/controllers/pokemons_controller.rb
 def show
   @pokemon = Pokemon.find(params[:id]) # 変更する
 end
```

パラメーター（数値）は、どこで指定すればよいでしょうか。
URLにパラメーターを含めて渡すテクニックがあるので覚えておきましょう。
例）IDが２のポケモンの情報を取得したい場合　
https://pokemon-zukan-[ランダムな文字列].run.goorm.site/pokemons/show/2
　 このままではルーティングエラーが表示されます。
　 **pokemons/show** へのリクエストに関しては記述していますが、 
　 **pokemons/show/(数字)**　へのリクエストについては何も書いていない為です。

config/routes.rb を開いてください。
URLに含まれる数字をパラメーターとして取得するには、下記のように記述します。

```ruby:config/routes.rb
Rails.application.routes.draw do
  get 'pokemons/index'
  get 'pokemons/show/:id', to:'pokemons#show', as: 'pokemon' # 変更する
  get 'pokemons/new'

end
```

こうすることで /pokemons/show/2　の 2の部分が、:id パラメーターとして利用可能になります。
( 利用するときは、params[:id] と書きます)

:::note
index と new は to: が書かれていませんね。
前章でも説明したとおり、Railsは、アクションが呼び出されると、
自動的に　**アクション名.html.erb**が呼び出されるので、
下記と同じ意味になります。
get 'pokemons/index' to: 'pokemonss#index'
get 'pokemons/new', to: 'pokemons#new'
:::

to: 'pokemons#show'　
pokemonsコントローラーの show アクションを呼び出す指示になります。

これで、任意のidのポケモンの情報を取得できるようになりました。

##### /pokemons/show/2

![スクリーンショット 2023-04-19 12.31.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/29f10dbc-67fe-df83-f872-724e55f3495a.png)


##### pokemons/show/3
![スクリーンショット 2023-04-19 12.31.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/4986bdd8-ac35-36b7-ad11-d42f175c3e8b.png)


# Model 検索
今ポケモンの情報の取り出しに id を利用していますが、
id 以外のカラムを用いて取り出す方法も覚えておくと便利です。

コンソールを起動してください。 ( ターミナルで`rails c`で起動 )
下記を参考に色々と試してみてください。

```ruby:railsコンソール
>> Pokemon.all
   #pokemonテーブルのすべてのデータを取得します。
>> Pokemon.find_by(name: "ヒトカゲ")
   #条件に合ったデータを、１件だけ取得します。
>> Pokemon.where(zokusei: "みず")
   #条件に合ったデータを、すべて取得します。
>> Pokemon.where(zokusei: "みず").where(number: 7)
   #AND検索。　みずタイプで ずかん番号番を取得しています。
>> Pokemon.where("(zokusei = ?) OR (number = ?)","みず",7)
   #OR検索。　みずタイプ　または　ずかん番号7番のポケモンを取得しています。
>> Pokemon.order(create_at: :asc)
   #並び順を指定します。　作成日時の昇順で取得しています。
```


# データ登録フォームの作成
データベースから情報を取り出したり加工したりする方法は覚えました。
しかしこのままではポケモンを登録することができません。

ポケモンを登録するための機能を作成する方法を学んでいきましょう。
form_withを使用します。

#### form_with
参考↓
[【Rails】 form_withの使い方を徹底解説！](https://pikawaka.com/rails/form_with)

データベースに新しいデータを保存したいので、 Model を呼び出します。
`app/views/pokemons/new.html.erb`に登録フォームを置きたいので、
`pokemons_controller.rb`のnewアクション内に書きましょう。
新しいデータを登録するときは、 Model名.new とします。下記のコードを追記してください。

```diff_ruby:app/controllers/pokemons_controller.rb
  # (中略)
  def new
    @pokemon = Pokemon.new # これを追加する
  end
```

`new.html.erb`に入力フォームを作成していきましょう。
railsでは、フォームを簡単につくれる`form_with`ヘルパーというものがあります。

```erb:app/views/pokemons/new.html.erb
<div class="container mt-6">
  <div class="columns">
    <div class="column is-three-fifths is-offset-one-fifth">
      <%= form_with model: @pokemon, url: { action: :create }, local: true do |f| %>
        <!-- 	エラーメッセージ	 -->
        <% if @pokemon.errors %>
          <% @pokemon.errors.full_messages.each do |message| %>
		    <div class='alert'>
		      <ul>
          　　   <li><%= message %></li>
			  </ul>
			</div>
          <% end %>
      　<% end %>
		<!-- 	ここまでエラーメッセージ	 -->
        <div class="field">
          <%= f.label :name, "なまえ", class: 'label'%>
          <div class="control">
            <%= f.text_field :name, class:'input'%>
          </div>
        </div>
        <div class="field">
          <%= f.label :number, "ばんごう", class: 'label' %>
          <div class="control">
            <%= f.text_field :number, class: 'input'%>
          </div>
        </div>
        <div class='field'>
          <%= f.label :zokusei, "タイプ", class: 'label' %>
          <div class="control">
            <%= f.text_field :zokusei, class: 'input'%>
          </div>
        </div>
        <div class="field">
          <%= f.label :description, "せつめい", class: 'label' %>
          <div class="control">
            <%= f.text_area :description, class: 'textarea' %> 
          </div>       
        </div>
        
        <div class="file">
          <label class="file-label"></label>
        </div>
        <br/>
        <br/>
        <div class="file is-boxed">
            <label class="file-label">
            <%= f.file_field :image, class: 'file-input'%>
              <span class="file-cta">
                  <span class="file-icon">
                      <i class="fas fa-upload"></i>
                  </span>
                  <span class="file-label">
                    <%= f.label :image, 'がぞう', class: 'label'%>
                  </span>
             </span>
          </label>
        </div>
        
        <%= f.submit "登録", class: 'button is-link'%>
      <% end %>
    </div>
  </div>
</div>
```
ここでは重要な部分だけ、簡単に解説します。
上の form_withヘルパーにより、下記のような HTML が生成されます。（少しシンプル化してます）

```html:
<form action="/pokemons" accept-charset="UTF-8" data-remote="true" method="post">
  <input type="hidden" name="authenticity_token" value="Nbbcp8B2ekJyks0THuIdAQcyafXQJdj7reyZeAkZbkLreXymKvbIwE6rL9pXcN58G2ZOrdlWFDHz5uXAkMNNqQ==">
        <div class="field">
          <label class="label" for="pokemon_name">なまえ</label>
          <div class="control">
            <input class="input" type="text" name="pokemon[name]" id="pokemon_name">
          </div>
        </div>
        <div class="field">
          <label class="label" for="pokemon_number">ばんごう</label>
          <div class="control">
            <input class="input" type="text" name="pokemon[number]" id="pokemon_number">
          </div>
        </div>
          
        <div class="field">
          <label class="label" for="pokemon_zokusei">タイプ</label>
          <div class="control">
            <input class="input" type="text" name="pokemon[zokusei]" id="pokemon_zokusei">
          </div>
        </div>
        
        <div class="field">
          <label class="label" for="pokemon_description">せつめい</label>
          <div class="control">
            <textarea class="textarea" name="pokemon[description]" id="pokemon_description"></textarea>        
        </div>
        
         <div class="field">
          <div class="file">
            <label class="file-label">
              <%= f.file_field :image, class: 'file-input'%>
              <span class="file-cta">
                <span class="file-label">
                がぞうをえらんでください
                </span>
              </span>
            </label>
          </div>
        </div>
        <input type="submit" name="commit" value="登録" class="button is-link" data-disable-with="登録">
    </div></form>
```

ここで重要な属性は、 
`<form action="/pokemons" accept-charset="UTF-8" data-remote="true" method="post">`
の中の、 **action="/pokemons"** と **method="post"** の２つです。

この２つは送信ボタンが押されたら、 
**/pokemons に対して、 POST リクエストを送信する**
という指示をしています。

なので、 /pokemons に対して、 POST リクエストがあった場合の処理を書いていきましょう。
送信したあとは、pokemons_controller の create アクションに飛ばしたいです。
(後ほどデータベースに保存する処理を create アクションに書いていきます）

`post 'pokemons', to: 'pokemons#create' `
コードはこのようになるので、 routes.rb に追記しましょう。
```diff_ruby:config/routes.rb
Rails.application.routes.draw do
   get 'pokemons/index'
    get 'pokemons/show/:id', to:'pokemons#show', as: 'pokemon' # 変更する
   get 'pokemons/new'
   post 'pokemons', to: 'pokemons#create'  # 追記する
end
```

***
１. 登録ボタンが押される
２. フォームに入力されたデータを、create アクションに飛ばす

という流れで、データが動いているので最後に、
create アクションの中で情報をデータベースに保存する処理を書きます。Modelを呼び出します。

```terminal:
Parameters: {...(中略)... "pokemon"=>{"name"=>"フシギダネ", "number"=>"1", "zokusei"=>"くさ", "description"=>"（中略）"
```

パラメーターをみると、二重の連想配列になっているのがわかると思います。
（　parameters{} の中に pokemon{} が入っている　）

通常の連想配列の場合は、**params[:title]**　として取得できていました。
二重の連想配列の場合は、**params[:pokemon][:title]**　とすることで取得できます。
（ **pokemonキー の中のtitleキー** のデータを取得しています　）
　連想配列について詳しくはこちらを参照してください　[Array(配列)とHash(連想配列)入門](https://qiita.com/kentarok/items/5d38c3f7df37a7396ef9)

さて、ここまで理解できていれば create アクションの中身も想像できると思います。
( seed.rb の、ポケモンの情報が書かれていた部分をパラメーターの中身に書き換えるだけです )
`def new ~ end`の下に下記を追記してください
```rb:app/controllers/pokemons_controller.rb
(中略)
def create
    @pokemon = Pokemon.new
    @pokemon.name = params[:pokemon][:name]
    @pokemon.zokusei = params[:pokemon][:zokusei]
    @pokemon.number = params[:pokemon][:number]
    @pokemon.description  = params[:pokemon][:description]
    @pokemon.image = params[:pokemon][:image]
    @pokemon.save
    redirect_to @pokemon
end
```

最後の、redirect_to '/pokemons/show/1'　の部分ですが、
登録ボタンを押したあとに、画面遷移してほしいので、リダイレクト先を指定しました。

https://pokemon-zukan-[ランダムな文字列].run.goorm.site/pokemons/new ここでポケモンの情報を登録
![スクリーンショット 2023-04-19 12.32.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/452548e4-5367-67ef-bb55-702c53be9e04.png)

https://pokemon-zukan-[ランダムな文字列].run.goorm.site/pokemons/show/[ID]
 ここで登録内容を確認

このままでは自由にポケモンを登録できる状態です。
numberは数値を入力してもらいたいので入力制限をかけてみましょう。

Rails では制限(validation)も簡単に設定することができます。

## バリデーション
#### バリデーションとは

:::note
データを保存する前に、無効なデータでないことを検証する機能のこと。門番みたいなもの。
空のデータが保存されないようにしたり、数字以外は保存できないようにしたり、文字数に制限を設けたり、保存するデータに制限をかける時に使います。
:::

app/models/pokemon.rb を開き、
下記の２行を`class Pokemon ~~ end`の間に入力してください。


::: note 
`numericality: true`
**属性に数値のみが使われている事を検証する**
`presence: true`
**必須項目にする**
:::

```ruby:app/models/pokemon.rb
class Pokemon < ApplicationRecord
  has_one_attached :image
  validates :name, :image,  presence: true # 追記する
  validates :number, numericality: true # 追記する
end

```
これだけで制限を設けることができます。

次に`pokemons_controller.rb`の`create`メソッドを編集します
```ruby:app/controllers/pokemons_controller.rb
def create
  @pokemon = Pokemon.new
  @pokemon.name = params[:pokemon][:name]
  @pokemon.zokusei = params[:pokemon][:zokusei]
  @pokemon.number = params[:pokemon][:number]
  @pokemon.description  = params[:pokemon][:description]
  @pokemon.image = params[:pokemon][:image]
  @pokemon.save
  if @pokemon.save
	redirect_to controller: :pokemons, action: :index
  else
    render "new"
  end
end
```

Pokemon Model に追記しているので、 pokemons テーブルの numberカラムに対して制限をかけます。
実際に試してみると、ポケモンいちらんに登録されていません。


これでポケモンのばんごうを数値以外入力して保存すると
上部にメッセージが出ます。
そして数値を入力して保存するとポケモンいちらんページに遷移先します
![スクリーンショット 2022-06-28 16.42.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/c80af4b6-5fb5-893b-122c-24ef7c9d1dff.png)



# ポケモン一覧ページの作成
しかし、これだとポケモンを登録しても
遷移先の https://pokemon-zukan-[ランダムな文字列].run.goorm.site/pokemons/index　は何も表示されていません
最後に登録したポケモンを一覧するページを作成しましょう。

まずはコントローラーの編集です。
先程コンソールで`Pokemon.all`を実行するとすべてのポケモンが表示されましたね。
それを利用しましょう。
```ruby:app/controllers/pokemons_controller.rb
class PokemonsController < ApplicationController
  def index
    @pokemons = Pokemon.all # これを追加する
  end
# （省略）
```
#### ビューの編集
app/views/pokemons/index.html.erbを編集しましょう。
```erb:app/views/pokemons/index.html.erb
<div class="container mt-6">
  <h1 class="title has-text-centered"> ポケモンいちらん </h1>
  <div class="columns is-multiline">
    <% @pokemons.each do |p| %>
      <div class="column is-one-quarter">
        <div class="pokemon-card">
          <%= image_tag p.image.variant(resize_to_limit: [100, 100])%>
          <div class="p-name">
            <p> NO. <%= p.number %> </p>
            <p class="vertical-middle"><%= link_to p.name, pokemon_path(p) %></p>
          </div>
        </div>
      </div>
      <% end %>
  </div>
</div>
```
![スクリーンショット 2023-04-19 12.39.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/de0bf760-3fda-3904-b821-2782eb63707b.png)

このように`seed.rb`で入れたデータや自分で入力したデータが表示されていれば完成です、お疲れ様でした！



### ポケモン図鑑一覧ページ
![スクリーンショット 2023-04-19 12.41.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/e7bcb622-f13e-8c0e-9b72-4825d0b063a5.png)

### ポケモン詳細ページ
![スクリーンショット 2023-04-19 12.42.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/3a89ceaa-869e-5ab4-55ac-f4fad2d96229.png)

### ポケモン登録ページ
![スクリーンショット 2023-04-19 12.42.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33092/90f67feb-9ab0-3689-917a-5b5f7d53a8c7.png)