学生向けプログラミング入門 | 無料

学生向けにプログラミングを無料で解説。Java、C++、Ruby、PHP、データベース、Ruby on Rails, Python, Django

Rails6.0 | 仕事売買サイトの構築 | 33 | 検索ページ

[32]レビュー << [ホームに戻る] >> [34]検索の実装


検索ページを作成していきます。


「app\controllers\pages_controller.rb」ファイルを以下のように編集します。


記述編集 app\controllers\pages_controller.rb

class PagesController < ApplicationController

  def home
  end

  def search
    @categories = Category.all
    @category = Category.find(params[:category]) if params[:category].present?
  end

end



ルートの設定をします。


記述追加 config\routes.rb
19行目に「get '/search', to: 'pages#search'」の記述を追加しています。

Rails.application.routes.draw do

  # ルートを app\views\pages\home.html.erb に設定
  root 'pages#home'

  devise_for :users, 
              path: '', 
              path_names: {sign_up: 'register', sign_in: 'login', edit: 'profile', sign_out: 'logout'},
              controllers: {omniauth_callbacks: 'omniauth_callbacks', registrations: 'registrations'}

  get 'pages/home'
  get '/dashboard', to: 'users#dashboard'
  get '/users/:id', to: 'users#show'
  get '/selling_orders', to: 'orders#selling_orders'
  get '/buying_orders', to: 'orders#buying_orders'
  get '/all_requests', to: 'requests#list'
  get '/request_offers/:id', to: 'requests#offers', as: 'request_offers'
  get '/my_offers', to: 'requests#my_offers'
  get '/search', to: 'pages#search'

  post '/users/edit', to: 'users#update'
  post '/offers', to: 'offers#create'
  post '/reviews', to: 'reviews#create'

  put '/orders/:id/complete', to: 'orders#complete', as: 'complete_order'
  put '/offers/:id/accept', to: 'offers#accept', as: 'accept_offer'
  put '/offers/:id/reject', to: 'offers#reject', as: 'reject_offer'

  resources :gigs do
    member do
      delete :delete_photo
      post :upload_photo
    end
    resources :orders, only: [:create]
  end

  resources :requests

  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end



「app\views\pages」フォルダに「search.html.erb」ファイルを新規作成します。


app\views\pages\search.html.erb(新規作成したファイル)

<%= render 'shared/categories' %>

<section class="section">
    <div class="container">

        <!-- ヘッダー -->
        <div class="card m-b-20">
            <div class="card-header">

                <!-- カテゴリー -->
                <div class="card-header-title">
                     カテゴリー <% if @category %><%= @category.name %> <% end %>                   
                </div>

                <!-- 並び替え -->
                <div class="field p-10">
                    <div class="select">
                             <%= select_tag 'sort', options_for_select(
                                [
                                    ['価格が低い順', 'price asc'],
                                    ['価格が高い順', 'price desc'],
                                    ['新着順', 'gigs.created_at desc'],
                                    ['古いもの順', 'gigs.created_at asc']
                                ], selected: @sort
                            ), onchange: "this.form.submit();" %>                       
                    </div>
                </div>              
            </div>
        </div>
        
        <div class="columns">

            <!-- 左側 -->
            <div class="column is-one-quarter">
                <div class="columns is-multiline">

                    <div class="column is-full">
                        <div class="card">
                            <div class="card-content">
                                                                    
                                <!-- タイトル検索 -->
                                <div class="field">
                                    <input class="input" type="text" placeholder="タイトルで検索">
                                </div>
                                <hr/>

                                <!-- 価格検索 -->
                                <label class="label">価格帯</label>
                                <div class="field has-addons">
                                    <p class="control">                                            
                                        <input class="input" type="text" placeholder="最低">                                            
                                    </p>
                                    <p class="control">
                                        <a class="button is-static"></a>
                                    </p>
                                </div>
                                <div class="field has-addons">
                                    <p class="control">
                                        <input class="input" type="text" placeholder="最高">
                                    </p>
                                    <p class="control">
                                        <a class="button is-static"></a>
                                    </p>
                                </div>
                                <hr/>

                                <!-- 期日 -->
                                <label class="label">期日</label>                                    
                                <%= radio_button_tag 'delivery', "1", checked = "1" == @delivery %> 1日以上 <br>
                                <%= radio_button_tag 'delivery', "3", checked = "3" == @delivery %> 3日以上 <br>
                                <%= radio_button_tag 'delivery', "7", checked = "7" == @delivery %> 7日以上 <br>
                                <%= radio_button_tag 'delivery', "10", checked = "10" == @delivery %> 10日以上 <br>
                                <%= radio_button_tag 'delivery', "15", checked = "15" == @delivery %> 15日以上 <br>
                                <%= radio_button_tag 'delivery', "0", checked = "0" == @delivery %> 全て
                                <hr/>
                                
                                <!-- 下部 -->
                                <div class="field m-t-20">
                                    <button  class="button is-danger is-fullwidth" type="submit"> 検索</button>
                                </div>

                                <div class="field m-t-10">
                                    <button  class="button is-black is-outlined is-fullwidth" type="submit"> 検索条件をクリア</button>
                                </div>

                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 右側 -->
            <div class="column infinite-list">

                <!-- お仕事のリスト -->
                <div class="columns is-multiline">
                    
                </div>

                <!-- ページネーション -->
                <div class="card">
                    <div class="card-header-title is-centered">
                        
                    </div>
                </div>
            </div>

        </div>
        
    </div>
</section>



ナビゲーションバーの記述を変更します。


記述変更 app\views\shared\_navbar.html.erb
64行目の記述を「<% if (user_signed_in?) && !current_page?(root_path) && !current_page?(search_path) && !current_page?("/gigs/#{params[:id]}") && !current_page?("/users/#{params[:id]}") %>」に変更しています。

<nav class="navbar is-danger" role="navigation" aria-label="main navigation">
    <div class="navbar-brand">
        <a class="navbar-item" href="/">
            <h1>テストサイトOshigoto</h1>
        </a>
        <a role="button" class="navbar-burger burger" aria-label="menu" aria-expanded="false" data-target="navbarBasicExample">
            <span aria-hidden="true"></span>
            <span aria-hidden="true"></span>
            <span aria-hidden="true"></span>
        </a>
    </div>

    <div id="navbarBasicExample" class="navbar-menu">
        <div class="navbar-start">
            <div class="navbar-item">
                <div class="field has-addons">
                    <div class="control">
                        <input class="input" type="text" placeholder="どんなお仕事を?">
                    </div>
                    <div class="control">
                        <a class="button is-success">検索</a>
                    </div>
                </div>
            </div>
        </div>
        <div class="navbar-end">
            <a class="navbar-item"></a>
            <a class="navbar-item"></a>
            
            <!-- もしログインしていなかったら-->
            <% if (!user_signed_in?) %>
                <div class="navbar-item">
                    <div class="buttons">
                        <%= link_to  "新規ユーザ登録", new_user_registration_path, class: "button is-primary" %>
                        <%= link_to  "ログイン", new_user_session_path, class: "button is-light" %>
                    </div>
                </div>

            <!-- ログインしていたら -->
            <% else %>
                <div class="navbar-item has-dropdown is-hoverable">

                    <a class="navbar-item" style="margin-right: 50px;">
                        <figure class="image is-48x48 m-r-5">
                            <div style="margin-top: 0.6rem;">
                            <%= image_tag avatar_url(current_user), class: "is-rounded" %>
                            </div>
                        </figure>                                        
                        <%= current_user.full_name %>
                    </a>
                    
                    <div class="navbar-dropdown">
                        <%= link_to 'ダッシュボード', dashboard_path, class: "navbar-item" %>
                        <%= link_to  "ユーザ登録情報編集", edit_user_registration_path, class: "navbar-item" %>
                        <hr class="navbar-divider">
                        <%= link_to  "ログアウト", destroy_user_session_path, method: :delete, class: "navbar-item" %>
                    </div>
                </div>
            <% end %>
        </div>
    </div>
</nav>

<% if (user_signed_in?) && !current_page?(root_path) && !current_page?(search_path) && !current_page?("/gigs/#{params[:id]}") && !current_page?("/users/#{params[:id]}") %>
    <nav class="navbar has-shadow" style="z-index: 5;">
        <div class="container">
            <div class="navbar">
                <%= link_to 'ダッシュボード', dashboard_path, class: "navbar-item" %>
                <div class="navbar-item has-dropdown is-hoverable">
                    <a class="navbar-link">お仕事を売る人</a>
                    <div class="navbar-dropdown">
                        <%= link_to 'お仕事を登録する', new_gig_path, class: "navbar-item" %>
                        <%= link_to '売れた注文の確認', selling_orders_path, class: "navbar-item" %>
                        <%= link_to 'リクエストを見る', all_requests_path, class: "navbar-item" %>
                        <%= link_to '申込みの確認', my_offers_path, class: "navbar-item" %>
                    </div>
                </div>
                <div class="navbar-item has-dropdown is-hoverable">
                    <a class="navbar-link">お仕事を買う人</a>
                    <div class="navbar-dropdown">
                        <%= link_to '買った注文の確認', buying_orders_path, class: "navbar-item" %>
                        <%= link_to 'お仕事をリクエストする', new_request_path, class: "navbar-item" %>
                        <%= link_to 'リクエストの確認', requests_path, class: "navbar-item" %>
                    </div>
                </div>
            </div>
        </div>
    </nav>
<% end %>

<script>
$(document).ready(function() {
  // Check for click events on the navbar burger icon
  $(".navbar-burger").click(function() {
      // Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu"
      $(".navbar-burger").toggleClass("is-active");
      $(".navbar-menu").toggleClass("is-active");
  });
});
</script>



「app\views\shared\_categories.html.erb」ファイルの記述を変更します。


記述変更 app\views\shared\_categories.html.erb
5行目の記述を「<%= link_to "#{item.name}", search_path(category: item.id), class: "navbar-item" %>」に変更しています。

<nav class="navbar has-shadow" style="z-index: 3">
    <div class="container">
        <div class="navbar">
            <% @categories.each do |item| %>
              <%= link_to "#{item.name}", search_path(category: item.id), class: "navbar-item" %>
            <% end %>
        </div>
    </div>
</nav>



ブラウザ確認
http://localhost:3000/search


まだ機能しません。

お仕事検索ページ
お仕事検索ページ



fakerで仕事サンプルを登録します。

  • 「gig_cover_1.jpg」「gig_cover_2.jpg」「gig_cover_3.jpg」の3つの画像ファイルを「app\assets\images」フォルダに入れておいてください。何でも良いです。
  • 「db\seeds.rb」ファイルの34から45行目をコメントアウトします。
  • その後、47行目からの記述を追加します。



コメントアウトは範囲選択して「Command+K」のあとに「Command+C」で一気にできます。


記述追加 db\seeds.rb

# This file should contain all the record creation needed to seed the database with its default values.
# The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup).
#
# Examples:
#
#   movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
#   Character.create(name: 'Luke', movie: movies.first)

# テストカテゴリーを追加(10個)
# 10.times do
#     Category.create(
#         name: Faker::Job.unique.field
#     )
# end

# テストユーザーを追加(5ユーザー パスワードは 123456)
# 5.times do
#     user = User.create(
#         full_name: Faker::Name.name,
#         email: Faker::Internet.free_email,
#         about: Faker::Quote.matz,
#         password: '123456',
#         from: Faker::Address.country,
#         language: Faker::Nation.language,
#         created_at: Date.today
#     )
#     user.avatar.attach(                
#         io: image = open("https://i.pravatar.cc/300"),
#         filename: "avatar#{user.id}.jpg", 
#         content_type: 'image/jpg'
#     )
# end

# 10.times do
#     random_user = User.all.sample(1)[0]
#     category = Category.all.sample(1)[0]
#     request = Request.create(
#         title: Faker::Job.title,
#         description: Faker::Quote.matz,
#         budget: Faker::Number.between(500, 5000),
#         delivery: Faker::Number.between(1, 30),
#         user_id: random_user.id,
#         category_id: category.id
#     )
# end

10.times do
    random_user = User.all.sample(1)[0]
    category = Category.all.sample(1)[0]
    gig = Gig.create(
        title: Faker::Job.unique.title,
        description: Faker::Quote.matz,
        active: Faker::Boolean.boolean,
        user_id: random_user.id,
        category_id: category.id
    )
    number = Faker::Number.between(1, 3)
    gig.photos.attach(
        io: File.open("app/assets/images/gig_cover_#{number}.jpg"),
        filename: "category_#{number}.jpeg"
    )    
    gig.pricings.create(
        pricing_type: 0,
        title: Faker::Job.title,
        description: Faker::Quote.matz,
        price: Faker::Number.between(500, 1500),
        delivery_time: Faker::Number.between(1, 10),
    )
    gig.pricings.create(
        pricing_type: 1,
        title: Faker::Job.title,
        description: Faker::Quote.matz,
        price: Faker::Number.between(2000, 10000),
        delivery_time: Faker::Number.between(11, 19),
    )
    gig.pricings.create(
        pricing_type: 2,
        title: Faker::Job.title,
        description: Faker::Quote.matz,
        price: Faker::Number.between(15000, 30000),
        delivery_time: Faker::Number.between(20, 30),
    )
end



コマンド
rails db:seed


Posticoでgigsテーブルを確認します。

gigsテーブル確認
gigsテーブル確認



検索のテストに使うので「active」を「true」に変更しておいて下さい。

「active」を「true」
「active」を「true」



↓↓クリックして頂けると励みになります。


[32]レビュー << [ホームに戻る] >> [34]検索の実装