LoginSignup
0
0

Railsでポケモン図鑑を作ろう 課題

Last updated at Posted at 2022-07-13

はじめに

本記事はRailsでポケモン図鑑を作ろうで作成したアプリケーションに課題として機能を追加していきます。様々なヒントややり方を載せていますので参考にしてチャレンジしてください。

1. 編集機能

投稿したものの内容を変更できる機能があると便利です。
ポケモンの情報を編集できる機能を実装していきましょう。

1.1 routes・controllers・view の3点に、編集ページを新規作成する

まずはconfig/routes.rbを編集します。

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'
  # 以下の2行を追加
  get 'pokemons/:id/edit', to: 'pokemons#edit', as: 'edit_pokemon'  
  patch 'pokemons/:id/', to: 'pokemons#update'
  # ここまで
end

データを更新するアクションは、HTTPメソッドの「PATCH」または「PUT」を使用します。
patchとputのどちらを使うか迷った場合は、Railsで推奨されているpatchを使用しましょう。

as:オプションを使うとルーティングに名前を指定できます。
上記だと、名前付きヘルパーとしてedit_pokemon_pathedit_pokemon_urlが作成されます。
edit_pokemon_pathを呼び出すとpokemons/:id/editが返されます。

次にpokemons_controller.rbのcreateアクションの下にeditアクションを作成します。

ap/controllers/pokemons_controller.rb
def create
    # 省略
end

# 下の3行を追加
def edit
  @pokemon = Pokemon.find(params[:id])
end
# ここまで

アクション名は「edit」です。
編集ページで必要な情報は、「一つのpokemon」です。
よって、今回は「params[:id]」で、一つだけidを取得します
これはshowアクションと同様のことを行っています。

次にビューを作成します。
コマンドプロンプトで下のコマンドを実行すると、edit.html.erbが生成します。
(エディタから新規ファイルを作成からでも構いません)

app/views/pokemons/edit.html.erbは下記のようにしましょう。

コードはこちら(クリックしてください)
app/views/pokemons/edit.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:"/pokemons/#{@pokemon.id}", 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でモデルにインスタンス変数を渡すことで(model:@pokemon)、編集したいポケモンの情報が既にフォーム内に入っています。
フォームはnew.html.erbのときとほとんど同じです。

そして、再びコントローラにコードを追加していきます。
app/controllers/pokemons_controller.rbのeditアクションにupdateアクションを追加します。

app/controllers/pokemons_controller.rb
def edit
  @pokemon = Pokemon.find(params[:id]
end

# ここから追加する
def update
  pokemon = Pokemon.find(params[:id])
  pokemon.update(pokemon_params)
  redirect_to pokemon_path(pokemon.id) 
  #  ↑ ポケモンのshowページに移動する
  end
	
  private
  
  def pokemon_params
    params.require(:pokemon).permit(:name, :zokusei, :number, :description, :image)
  end
# ここまで追加する

最後にポケモン詳細ページに編集ページのリンクを貼りましょう。

app/views/pokemons/show.html.erb
(中略)
<div class="column is-8">
  <div class="p-description">
    <%= @pokemon.description %>
  </div>
  <p class="p-edit"> <%= link_to 'へんしゅう', edit_pokemon_path, class: 'button is-info'%> </p> 
    <!-- 上の1行を追加する -->
(中略)
</div>

ポケモン検索機能

検索機能には色々とありますが、ポケモン名を完全一致で検索できるものを作っていきます。

1.検索フォームを作成する

既存にあるindex.html.erbの上部に検索フォームを追加します。
new.html.erbやedit.html.erbとほとんど似ていますが、
:searchなど、検索に関わるカラムを追加しています。

app/views/app/pokemons/index.html.erb
<!-- ここから -->
  <div class="field has-addons">
  <div class="control">
     <%= form_with(url: pokemons_index_path, class: 'search_form', method: :get, local:true) do |f| %>
     <%= f.text_field :search, class:'field', value: params[:search], placeholder: "ポケモンけんさく", class: 'input'%>
  </div>
  <div class="control">
    <%= f.submit 'けんさく', class: "button is-info" %>
    <% end %>
  </div>
</div>
<!-- ここまで -->

<div class="container mt-6">
  <h1 class="title has-text-centered"> ポケモンいちらん </h1>
  <!-- 省略 -->
</div>
2.コントローラーの編集

pokemon_controller.rbのindexアクションを以下に書き換えましょう。
indexアクション内1行目の@pokemons = Pokemon.allは一覧ページが表示されたときは登録しているポケモンすべてを表示するようにしており、
indexアクション2行目の@pokemons = params[:search].present? ? Pokemon.pokemon_serach(params[:search]) : Pokemon.allは検索フォームに入力されたものがPokemonモデルにあるかどうかを判定し、存在していれば、@pokemonsにいれ、表示をします。存在していなかったら、ポケモンすべてを表示します。

app/controllers/pokemon_controller.rb
class PokemonsController < ApplicationController
  def index
    @pokemons = params[:search].present? ? Pokemon.pokemon_serach(params[:search]) :  Pokemon.all
  end
3.モデルの編集

検索機能の詳しい実装はモデル内でしていきましょう。

app/models/pokemon.rb
class Pokemon < ApplicationRecord
  (省略)
  
  def self.pokemon_serach(search)
    Pokemon.where(['name LIKE ?', "%#{search}%"])
  end
end

ポケモンいちらんページで名前を検索(カタカナで)すると
一致したポケモンのみ表示されます。

詳しく知りたい人は以下のサイトを参考にしてください。

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