Waku×2 プログラミング生活

駆け出しエンジニアが楽しみながら成長していくブログ

カレンダーの曜日を日本語化する、日付表示の微調整(一桁のときの最初の0を取り除く)

Simple Calendarでカレンダーを実装した時に、カレンダーの曜日が英語だったため、日本語化しました。
メモとして残しておきます。

弄るのは
config/locales ディレクトリです。

ディレクトリ内に
ja.yml という新規ファイルを作成して、
以下の様に定義してあげるだけです!

ja:
 date:
    abbr_day_names:
    - 日
    - 月
    - 火
    - 水
    - 木
    - 金
    - 土

また、日付も一桁のときに「01」「02」「03」…という様にデフォルトでは表示されてしまっていたので、
「1」「2」「3」…というフォーマットで表示させるようにしました。

弄った箇所は、
config/initializers/date_formats.rb
で、ファイルが無ければ作成します。

config/initializers/date_formats.rb

Date::DATE_FORMATS[:only_date] = '%e'

「%e」としてあげると良いみたいです。
変更したいviewファイルでは、

app/views/〇〇.html.haml

  日付.to_formatted_s(:only_date)

としてあげると、日付の一桁のときの最初の0が取り除かれて表示されます!
簡単!

参考ページ

すごくわかりやすくまとめてあります!^^
uxmilk.jp

simple calendarを使ってカレンダーを導入する

またまたスクールの最終課題で導入したものを書き残しておきます。
これがなかなか見た目的に面白く出来上がりました。
導入したものはこちら。
f:id:ywatanab0301:20181024180739p:plain

ユーザーのマイページにある「行ったカレンダー」というものです。
ユーザーが書いたレビューの訪問日にユーザーのアバターが表示されます。



手順

  1. simple_calendar のgemをインストールする。
  2. user model にstart_timeを定義する(3でイベントとカレンダーを結びつけるのに必要)
  3. viewファイルを編集する
  4. CSSファイルで見た目を整える


1. simple_calendar のgemをインストールする。

Gemfileに下記記述を追加。
Gemfile

gem "simple_calendar", "~> 2.0"

ターミナルでbundle installを実行する。

2. user modelにstart_timeを定義する

app/models/review.rb

def start_time
  self.visit_day
end

※visit_dayはreviewsテーブルのカラムの一つとして作成済み。(データ属性はdatetime)
下記3で再度登場します。

3. viewファイルを編集する

simple calendarは、カレンダー上に、登録したイベントを表示させることができます(例:●●さんとランチ 等)。
今回は、そのイベントタイトルの代わりにユーザーのアバター画像を表示させました。
viewファイルは下記のようにしました。

app/views/users/show.html.haml

= month_calendar events: @reviews do |date, reviews|
  = date
  - reviews.each do |review|
    .image-avatar
      = link_to shop_review_path(review.shop.id, review.id) do
        = image_tag review.user.avatar


順を追って解説していきます。
月カレンダーだけを表示させるためのviewは、

= month_calendar do |date|
  = date

とすれば済むのですが、カレンダー内にイベントを表示させるためには、上の記述に、「events: インスタンス変数」を追加する必要があります。
今回の場合は、ユーザーが投稿したレビューの訪問日カラムをカレンダーに結びつける必要があるため、コントローラで定義したインスタンス変数@reviewsを「events: インスタンス変数」の記述に使ってあげます。

events: @reviews

ちなみにUsersコントローラのshowアクション内に定義してあるインスタンス変数@reviewsはこちら。
app/controllers/users_controller.rb

def show
  @reviews = @user.reviews.includes(:shop)
end

次にユーザーのお店への訪問日にユーザーのアバター画像を表示させるための記述も追加してあげます。
eachでreviewsを展開。
「- reviews.each do |review|」



手順2でUserモデルでstart_timeを定義してvisit_dayをカレンダー日付と結びつけました。
それぞれのインスタンス「review」はデータ属性がDateTimeの:start_timeを持っている必要があり、
そのstart_timeを元にカレンダーの日付とイベント(ここではreview)とが結び付けられ表示されます。
なので、手順2で定義したstart_timeにより、reviewとカレンダーがvisit_day(訪問日)により結びつき、表示されることになります。

  = month_calendar events: @reviews do |date, reviews|
    = date
    - reviews.each do |review|
      .image-avatar
        = link_to shop_review_path(review.shop.id, review.id) do
          = image_tag review.user.avatar

「= image_tag review.user.avatar
これでeachで展開されたreviewインスタンスに紐づくuserのavatarをDBから取り出し表示できます。

※「= link_to shop_review_path(review.shop.id, review.id) do」は、表示されたアバターを該当レビューページへのリンク化しています。

4. CSSファイルで見た目を整える。

下記の様な雛形が用意されているため、そちらを使って見た目を整えれば完成です!

app/assets/stylesheets/_simple_calendar.scss

.simple-calendar {
  .day {}

  .wday-0 {}
  .wday-1 {}
  .wday-2 {}
  .wday-3 {}
  .wday-4 {}
  .wday-5 {}
  .wday-6 {}

  .today {}
  .past {}
  .future {}

  .start-date {}

  .prev-month {}
  .next-month { }
  .current-month {}

  .has-events {}
}

flexsliderでスライドショーを実装する

こちらもスクールでのチーム開発で使用したスライドショーの実装手順を書いておこうと思います。

下の画像(※食べログ本家の画像)のようなサムネイル画像つきのスライドショーを実装したかったので、色々調べたところ、flexsliderというjQueryプラグインで簡単に実装できる!
というのがあったので、そちらを使って実装してみました。が、意外とJSファイルやらCSSの調整など苦労したのであくまで私のケースですが、手順を書き残しておきます。

f:id:ywatanab0301:20181019145555p:plain



手順

1. FlexsliderのダウンロードページからFlexsliderのプラグイン一式zipファイルをダウンロードする。
2. application.html.hamlのhead部分にflexsliderのプラグインを読み込む記述をする。
3. app/assets/javascripts にflexslider.js というファイルを新たに作り、編集する。
4. view ファイルを編集する。
5. CSSファイルを編集してviewを整える。



1. FlexsliderのダウンロードページからFlexsliderのプラグイン一式zipファイルをダウンロードする。

flexslider2ダウンロードページはこちら

2. application.html.hamlのhead部分にflexsliderのプラグインを読み込む記述をする。

こちらにあるURLを拝借して、CDN上のJavascriptを読み込めるようにしてあげる。

app/views/layouts/application.html.haml

%head
  %script{src: "https://cdnjs.cloudflare.com/ajax/libs/flexslider/2.7.1/jquery.flexslider.min.js", rel: "stylesheet"}
3. app/assets/javascripts にflexslider.js というファイルを新たに作り、編集する。



app/assets/javascripts/flexslider.js

$(window).on('load', function() {
  $('#slider').flexslider({
    animation: "fade",
    prevText: "",
    nextText: "",
    controlsConatiner: '.flexslider-controls',
    manualControls: ".thumb li",
  });
});



4. view ファイルを編集する。



app/views/shops/show.html.haml

#slider.flexslider
  %ul.slides
    %li
      = image_tag @shop.pic1.url if @shop.pic1.present?
    %li
      = image_tag @shop.pic2.url if @shop.pic2.present?
    %li
      = image_tag @shop.pic3.url if @shop.pic3.present?
    %li
      = image_tag @shop.pic4.url if @shop.pic4.present?
    %li
      = image_tag @shop.pic5.url if @shop.pic5.present?
  .flexslider-controls
    %ul.thumb
      %li
        = image_tag @shop.pic1.url if @shop.pic1.present?
      %li
        = image_tag @shop.pic2.url if @shop.pic2.present?
      %li
        = image_tag @shop.pic3.url if @shop.pic3.present?
      %li
        = image_tag @shop.pic4.url if @shop.pic4.present?
      %li
        = image_tag @shop.pic5.url if @shop.pic5.present?

※「image_tag @shop.pic1.url 」の@shopはshopsコントローラで該当店舗のレコードを取得してインスタンス変数に代入したもののうち、pic1カラムに入っている画像データを取り出しています。「if @shop.pic1.present?」でデータが存在している時のみ表示させています。

5. CSSファイルを編集してviewを整える。

app/assets/stylesheets/_flexslider.scss
ここは、1でダウンロードしたzipファイルのうち、CSSファイルをsylesheetディレクトリに配置し、
application.scssでimportして、ブラウザの検証ツールでclass名やid名を参照しながら微調整しました。



じゃーん。完成しました!
下記サムネイル画像をクリックしても上段の画像が切り替わります!
f:id:ywatanab0301:20181019155610p:plain


参考にした記事

wpgatera.matrix.jp

Rails5でGoogleMapを表示させる

Rails5でGoogleMapを表示させる

 なんだかんだでブログを作ったはいいが、投稿できていなかったので、初投稿。

 

 現在プログラミングのスクールに通いながら作っている飲食店のレビューを管理するアプリケーション(食べログのクローンサイト)で、お店の詳細画面に地図を表示させたくて、GoogleMapを使って表示したくて試行錯誤した結果、数日かかったけれどとりあえず動くようになったのでメモとして書いておきます(とりあえず公開してあとで編集します!)。

 

 

やりたかったこと

  • お店の新規登録の際に入力した住所からお店の座標(緯度と経度)を割り出して、GoogleMapで表示させる。
  • 表示したお店の座標を登録して、お店のページでGoogleMapでお店の場所を表示させる。

やったこと

  • gemの導入(gmaps4rails, geocoder)
  • DBのテーブルにlatitudeとlongitudeカラムを追加する
  • application.html.hamlのhead部分にjQueryとGoogleAPIのscriptを読み込む記述を行う
  • underscore.jsをコピペ(Gmaps4railsが使うやつ)
  • jsファイルgooglemap.jsを編集
  • viewの編集
1. GoogleAPIキーの取得

Google Mapを使用するためにはGoogle APIを取得する必要があります。

以下のリンクや、「Google API 取得」等で検索して出てきたサイトを参考に取得しました。

https://developers.google.com/maps/documentation/javascript/get-api-key

取得したら、Maps JavaScript APIとGeocoding APIを有効化します。

 

2. gem の導入

Gemfileを編集します。

gem 'geocoder'
gem 'gmaps4rails'



3. データベースのテーブルにlatitudeとlongitudeカラムを追加する

 開発していたアプリケーションでは、店舗の情報を管理しているテーブルshopsテーブルに新しく店舗の座標を登録するため、latitudeカラムとlongitudeカラムを追加しました。

ターミナル

$ rails g migration AddMapInfoToShops 

Migration File ( db/migrate/xxxxxxxx_add_map_info_to_shops.rb )

class AddMapInfoToShops < ActiveRecord::Migration[5.0]
  def change
    add_column :shops, :latitude, :float
    add_column :shops, :longitude, :float
  end
end

 


4. application.html.hamlのhead部分にjQueryとGoogleAPIのscriptを読み込む記述を行う

1で取得して有効化したAPIキーを下記コードのYOUR_API_KEY部分に記述する。

app/views/layouts/application.html.haml

%script{:async => "", :defer => "defer", :src => "https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"}
%script{:src => "//cdn.rawgit.com/mahnunchik/markerclustererplus/master/dist/markerclusterer.min.js"}
5. underscore.jsをコピペ(Gmaps4railsが使うやつ)

underscore.jsのリンク
上のリンク先のコードをコピーして、underscore.js ファイルを作って中に貼り付けます。
app/assets/javascripts/underscore.js 

// underscore-min.jsの中身をコピペ。
6. jsファイルgooglemap.jsを編集
// 店舗新規登録画面
// Mapの表示
//マップオブジェクト
var gMap = null;
//マーカーオブジェクト
var gMarkerCenter = null;

function initMap(){
 // 緯度経度から地図を表示
  var lat = $('#shop_latitude').val();
  var lng = $('#shop_longitude').val();
// 座標を設定
  var myLatLng = new google.maps.LatLng(lat, lng)
  var mapOptions = {
    center: myLatLng,
    zoom: 15,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
// マップオブジェクトの生成、マーカー生成
  gMap = new google.maps.Map(document.getElementById("map"), mapOptions);
  gMarkerCenter = drawMarkerCenterInit(myLatLng);
}
// マーカー生成関数
function drawMarkerCenterInit(pos) {
  var markerCenter = new google.maps.Marker({
    position: pos,
    map: gMap,
    draggable: true
 });
  return markerCenter;
}

$(function(){
  // 検索ボタンをクリックした時
  $('#searchAddressBtn').click(function() {
    // Geocoderオブジェクト生成
    var geocoder = new google.maps.Geocoder();
    // 住所のテキストボックスから住所取得
    var address = $('.city_address').val();
    // 住所検索実行
    geocoder.geocode(
      {
        'address' : address,
        'region' : 'jp'
      },
      function (results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
          // 住所のデータを取得できた時
          // 取得した座標をマップに反映
          gMap.setCenter(results[0].geometry.location);
          // 取得した座標をマーカーに反映
          var pos = new google.maps.LatLng(results[0].geometry.location.lat(), results[0].geometry.location.lng());
          gMarkerCenter.setPosition(pos);

          // 取得した座標をテキストボックスにセット
          $('#shop_latitude').val(pos.lat());
          $('#shop_longitude').val(pos.lng());

          } else {
            // 失敗した時
              alert('住所検索に失敗しました。<br>住所が正しいか確認してください');
          }
      });
  });
});

// 店舗ページで地図を表示
$(function(){
  handler = Gmaps.build('Google');
  handler.buildMap({ provider: { scrollwheel: false }, internal: {id: 'map1'}}, function(){
    markers = handler.addMarkers([
      {
        "lat": gon.shop.latitude,
        "lng": gon.shop.longitude,
    "infowindow": '<p>'+ gon.shop.shop_name +'</p><p>'+ gon.shop.city_address +'</p><p> link_to "Googleマップで見る" ,"https://maps.google.co.jp/maps?q=loc:'+ gon.shop.latitude +','+ gon.shop.longitude +'&iwloc=J",target: "_blank"</p>'
      }
    ]);
    handler.bounds.extendWith(markers);
    handler.fitMapToBounds();
    handler.getMap().setZoom(16);
  });
});


7. viewの編集

お店の新規登録画面で、city_addressの入力フィールドに入力された住所を元に、
geocoderが座標を取得、すぐさま入力フィールド下にGoogleMapで表示させます。

app/views/shops/new.html.haml

//form_forを使って店舗の情報を保存する
= form_for @shop do |f|

//省略

//入力フィールド
  = f.text_field :city_address, class:"city_address"
    %button{id:"searchAddressBtn", value:"検索", type:"button"}
      場所を検索

//省略

//地図の描画
  #map{:style => "width: 100%; height: 160px;"}
            = f.text_field :latitude, readonly:"readonly"    //緯度の表示
            = f.text_field :longitude, readonly:"readonly" //経度の表示

//省略

//上記緯度と経度を店舗の情報と一緒にテーブルに保存する
  = f.submit "登録する", class: "submit_btn"


下記の様に、市町村区・番地の入力フィールドに住所を入力した後、検索ボタンを押すと、
その下のGoogleMap上に描画されます。
f:id:ywatanab0301:20181019110426p:plain


お店の情報ページでは、上記でお店の情報テーブルに保存された緯度と経度を取得することで、
GoogleMapを描画します。

app/views/shops/show_map.html.haml

#map{:style => "width: 100%; height: 600px;"}


こんな感じで表示されます。
f:id:ywatanab0301:20181019113318p:plain


GoogleのGeocoding APIは、その画面で即GoogleMapを表示させないといけないようです。