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

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

【民泊5.1】【MacOSX】検索

記述追加 GemFile
「gem 'ransack', '~> 1.7'」の記述追加(83行目)

source 'https://rubygems.org'

git_source(:github) do |repo_name|
  repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
  "https://github.com/#{repo_name}.git"
end


# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.0.7', '>= 5.0.7.1'
# Use postgresql as the database for Active Record
gem 'pg', '>= 0.18', '< 2.0'
# Use Puma as the app server
gem 'puma', '~> 3.0'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.2'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby

# Use jquery as the JavaScript library
gem 'jquery-rails'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.5'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 3.0'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platform: :mri
end

group :development do
  # Access an IRB console on exception pages or by using <%= console %> anywhere in the code.
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '~> 3.0.5'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

# bootstrap
gem 'bootstrap-sass', '~> 3.4.1'

# デバイス
gem 'devise', '~>4.2'

# Gravatar
gem 'gravtastic'

#フラッシュメッセージ
gem 'toastr-rails', '~> 1.0'

#日本語化
gem 'rails-i18n'

#画像アップロード
gem 'paperclip', '~> 5.1.0'

#googleマップ
gem 'geocoder', '~> 1.4'

#アマゾンS3
gem 'aws-sdk', '~> 2.8'

#日付ピッカー
gem 'jquery-ui-rails', '~> 5.0'

# 検索
gem 'ransack', '~> 1.7'



コマンド
bundle


記述追加 app\controllers\pages_controller.rb
「search()」メソッドの実装

class PagesController < ApplicationController

  def home
      @rooms = Room.where(active: true).limit(3)
  end
  
  def search

    # ステップ 1

    if params[:search].present? && params[:search].strip != ""
      session[:loc_search] = params[:search]
    end
    arrResult = Array.new

    # ステップ 2

    if session[:loc_search] && session[:loc_search] != ""
      @rooms_address = Room.where(active: true).near(session[:loc_search], 5, order: 'distance')
    else
      @rooms_address = Room.where(active: true).all
    end

    # ステップ 3

    @search = @rooms_address.ransack(params[:q])
    @rooms = @search.result
    @arrRooms = @rooms.to_a

    # ステップ 4
    
    if (params[:start_date] && params[:end_date] && !params[:start_date].empty? &&  !params[:end_date].empty?)
      start_date = Date.parse(params[:start_date])
      end_date = Date.parse(params[:end_date])
      @rooms.each do |room|
        not_available = room.reservations.where(
          "(? <= start_date AND start_date <= ?)
          OR (? <= end_date AND end_date <= ?)
          OR (start_date < ? AND ? < end_date)",
          start_date, end_date,
          start_date, end_date,
          start_date, end_date
        ).limit(1)
        if not_available.length > 0
          @arrRooms.delete(room)
        end
      end
    end
  end
  
end



記述追加 config\routes.rb
「get 'search' => 'pages#search'」の記述を追加(9行目)

Rails.application.routes.draw do

  #ルートをpages#homeに設定
  root 'pages#home'

  get 'pages/home'
  get '/your_trips' => 'reservations#your_trips'
  get '/your_reservations' => 'reservations#your_reservations'
  get 'search' => 'pages#search'

  resources :users, only: [:show]

  resources :rooms, except: [:edit] do
    member do
      get 'listing'
      get 'pricing'
      get 'description'
      get 'photo_upload'
      get 'amenities'
      get 'location'
      get 'preload'
      get 'preview'
    end
    resources :photos, only: [:create, :destroy]
    resources :reservations, only: [:create]
  end

  resources :guest_reviews, only: [:create, :destroy]
  resources :host_reviews, only: [:create, :destroy]

  devise_for :users,
  path: '',
  path_names: {sign_in: 'login', sign_out: 'logout', edit: 'profile', sign_up: 'registration'},
  controllers: {registrations: 'registrations'}
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end



記述更新 app\views\pages\home.html.erb
「<%= form_tag search_path, method: :get do %>」に記述変更(3行目)

<br/>
<br/>
<%= form_tag search_path, method: :get do %>
  <div class="row">
    <div class="col-md-6">
      <%= text_field_tag :search, params[:search], placeholder: "どちらのお部屋をおさがしですか?", class: "form-control" %>
    </div>
    <div class="col-md-3">
      <%= text_field_tag :start_date, params[:start_date], placeholder: "チェックイン", readonly: true, class: "form-control datepicker" %>
    </div>
    <div class="col-md-3">
      <%= text_field_tag :end_date, params[:end_date], placeholder: "チェックアウト", readonly: true, class: "form-control datepicker" %>
    </div>
  </div>
  <br/><br/>
  <div class="row">
    <div class="col-md-offset-4 col-md-4">
      <%= submit_tag "検索", class: "btn btn-normal btn-block" %>
    </div>
  </div>
<% end %>
<br/><hr/><br/>

<!-- ホーム -->
<div><h3>お部屋</h3></div>
<br/>
<div class="row">
  <% @rooms.each do |room| %>
      <div class="col-md-4">
        <div class="panel panel-default">
          <div class="panel-heading preview">
            <%= image_tag room.cover_photo(:medium) %>
          </div>
          <div class="panel-body">
            <%= link_to room.listing_name, room %>
          </div>
        </div>
      </div>
  <% end %>
</div>

<script>
  $('#start_date').datepicker({
    dateFormat: 'dd-mm-yy',
    minDate: 0,
    maxDate: '3m',
    onSelect: function(selected) {
      $('#end_date').datepicker("option", "minDate", selected);
      $('#end_date').attr("disabled", false);
    }
  });
  $('#end_date').datepicker({
    dateFormat: 'dd-mm-yy',
    minDate: 0,
    maxDate: '3m',
    onSelect: function(selected) {
      $('#start_date').datepicker("option", "maxDate", selected);
    }
  });
</script>



「app\views\pages」フォルダに「search.html.erb」ファイルを新規作成してください。


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

<div id="main">
  <div id="left">
    <!-- 検索パネル -->
    <div class="row">
      <br/>
      <div id="collapsePanel">

          <%= search_form_for @search, url: search_path, remote: true do |f| %>

              <div class="row">
                <div class="col-md-8">
                  <label>宿泊費(円)</label>
                </div>
                <div class="col-md-2">
                  <label>最低(円)</label>
                  <%= f.text_field :price_gteq, class: "form-control" %>
                </div>
                <div class="col-md-2">
                  <label>最高(円)</label>
                  <%= f.text_field :price_lteq, class: "form-control" %>
                </div>
              </div>
              <hr/>

              <div class="row">
                <div class="col-md-6">
                  <%= text_field_tag :start_date, params[:start_date], readonly: true, placeholder: "チェックイン日", class: "form-control datepicker" %>
                </div>
                <div class="col-md-6">
                  <%= text_field_tag :end_date, params[:end_date], readonly: true, placeholder: "チェックアウト日", class: "form-control datepicker" %>
                </div>
              </div>
              <hr/>

              <div class="row">
                <div class="col-md-4">
                  <%= check_box_tag "q[room_type_eq_any][]", "プライベート" %> プライベート
                </div>
                <div class="col-md-4">
                  <%= check_box_tag "q[room_type_eq_any][]", "シェア" %> シェア
                </div>
              </div>
              <hr/>

              <div class="row">
                <div class="col-md-4">
                  <div class="form-group select">
                    <label>宿泊人数</label>
                    <%= f.select :accommodate_gteq, [["1人", 1], ["2人", 2], ["3人", 3], ["4人以上", 4]], id: "accommodate", prompt: "選択してください", class: "form-control" %>
                  </div>
                </div>

                <div class="col-md-4">
                  <div class="form-group select">
                    <label>ベッド数</label>
                    <%= f.select :bed_room_gteq, [["1台", 1], ["2台", 2], ["3台", 3], ["4台以上", 4]], id: "bed_room", prompt: "選択してください", class: "form-control" %>
                  </div>
                </div>

                <div class="col-md-4">
                  <div class="form-group select">
                    <label>部屋数</label>
                    <%= f.select :bath_room_gteq, [["1部屋", 1], ["2部屋", 2], ["3部屋", 3], ["4部屋以上", 4]], id: "bath_rooms", prompt: "選択してください", class: "form-control" %>
                  </div>
                </div>
              </div>
              <hr/>

              <div class="row">
                <div class="col-md-4">
                  <%= check_box_tag "q[is_tv_eq]", true %> テレビ
                </div>
                <div class="col-md-4">
                  <%= check_box_tag "q[is_kitchen_eq]", true %> キッチン
                </div>
                <div class="col-md-4">
                  <%= check_box_tag "q[is_Internet_eq]", true %> インターネット
                </div>
                <div class="col-md-4">
                  <%= check_box_tag "q[is_heating_eq]", true %> 暖房
                </div>
                <div class="col-md-4">
                  <%= check_box_tag "q[is_air_eq]", true %> エアコン
                </div>
              </div>
              <hr/>

              <div class="row text-center">
                <%= f.submit "検索", class: "btn btn-form" %>
              </div>
          <% end %>
      </div>
      <br/>

      <div class="row">
        <% @arrRooms.each do |room| %>
            <div class="col-md-4">
              <div class="panel panel-default">
                <div class="panel-heading preview">
                  <%= image_tag room.cover_photo(:medium) %>
                </div>
                <div class="panel-body">
                  <%= link_to room.listing_name, room %>
                </div>
              </div>
            </div>
        <% end %>
      </div>


    </div>
  </div>



  <div id="right">
    <!-- GOOGLEマップ -->

    <div id="map" style="width: 100%; height: 100%"></div>

    <script src="https://maps.googleapis.com/maps/api/js"></script>
    <script>
        function initialize(rooms) {
          var location = {lat: 43.061771, lng: 141.354451}

          if (rooms.length > 0) {
            location = {lat: rooms[0].latitude, lng: rooms[0].longitude}
          }

          var map = new google.maps.Map(document.getElementById('map'), {
            center: location,
            zoom: 12
          });

          var marker, inforwindow;

          rooms.forEach(function(room) {
            marker = new google.maps.Marker({
              position: {lat: room.latitude, lng: room.longitude},
              map: map
            });

            inforwindow = new google.maps.InfoWindow({
              content: "<div class='map_price'>" + room.price + "円</div>"
            });

            inforwindow.open(map, marker);
          })
        }

        google.maps.event.addDomListener(window, 'load', function() {
          initialize(<%= raw @arrRooms.to_json %>)
        });
    </script>
    <script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBojDcZmScBkIOISjoYREjgid99iZUL2Tk&callback=initMap" type="text/javascript"></script>
  </div>



</div>


<script>
  $('#start_date').datepicker({
    dateFormat: 'dd-mm-yy',
    minDate: 0,
    maxDate: '3m',
    onSelect: function(selected) {
      $('#end_date').datepicker("option", "minDate", selected);
      $('#end_date').attr("disabled", false);
    }
  });

  $('#end_date').datepicker({
    dateFormat: 'dd-mm-yy',
    minDate: 0,
    maxDate: '3m',
    onSelect: function(selected) {
      $('#start_date').datepicker("option", "maxDate", selected);
    }
  });


</script>



ブラウザ確認
検索ができるようになりました。


http://localhost:3000/


検索画面
検索画面