Ruby on Rails開発のインターン (Day 18)

こんにちは、皆さん!

ついに今週もラスト1日!
昨日に引き続き、職場のプログラムでcapybaraテストが実行できるようにエラーの原因を探そうと思う。


  • トピック:
  1. Railsでdatabase cleanerを使う方法


  • 疑問:


  • 問題:
  1. capybaraテストが職場のプログラムで実行されない (解決した)


  • 学習した内容:
  1. テストの時に新しく追加されたデータを自動的に削除する方法


  • 今後やってみたいこと:
  1. Railsの'will-paginate'についてもっと学習する


  • リソース:
  1. GitHub - DatabaseCleaner/database_cleaner: Strategies for cleaning databases in Ruby. Can be used to ensure a clean state for testing.


Railsでdatabase cleanerを使う方法

毎回同じデータでテストを行うために、テスト環境のデータベースをもとの整理整頓された状態にキープしたいのはしばしばあることだ。というわけで、新しく作られたデータをお掃除する必要があるでしょう。

この目的のためにとても便利なジェムがある。そして、使い方も簡単。2ステップで完了。
***ここではRspecの場合だけについて言及する。CucumberとMinitestユーザーの方々すいません。***

最初に、ジェムのインストール。Gemfileに下記のを入れて、 bundle installコマンドを打ってください。

group :test do
  gem 'database_cleaner'
end

これをテストのグループに入れたのは同じデータをキープするためにデータベースのお掃除をするのはテスト環境の時だけでいいからだ。

次に、データベースお掃除の設定を書いていく。これは簡単で基本的には下記のをspec/spec_helper.rbファイルに入れればよい。

RSpec.configure do |config|

  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)
  end

  config.around(:each) do |example|
    DatabaseCleaner.cleaning do
      example.run
    end
  end

end

この設定はdb/seeds.rbの状態に還元するというものだ。つまり、新しく追加されたデータのみが削除されるということだ。 これは便利!!

おまけ:
もし、capybaraテストも使っているのなら、上記に挙げた設定の代わりに、下記のものを使った方がいい。capybaraテストで作ったデータがテストされる前に削除されてしまう可能性があり、エラーの原因になりかねないからだ。
***必ずrequire 'capybara/rspec'の後に下記のを入れてください!***

RSpec.configure do |config|

  config.use_transactional_fixtures = false

  config.before(:suite) do
    if config.use_transactional_fixtures?
      raise(<<-MSG)
        Delete line `config.use_transactional_fixtures = true` from rails_helper.rb
        (or set it to false) to prevent uncommitted transactions being used in
        JavaScript-dependent specs.

        During testing, the app-under-test that the browser driver connects to
        uses a different database connection to the database connection used by
        the spec. The app's database connection would not be able to access
        uncommitted transaction data setup over the spec's database connection.
      MSG
    end
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

  config.before(:each, type: :feature) do
    # :rack_test driver's Rack app under test shares database connection
    # with the specs, so continue to use transaction strategy for speed.
    driver_shares_db_connection_with_specs = Capybara.current_driver == :rack_test

    unless driver_shares_db_connection_with_specs
      # Driver is probably for an external browser with an app
      # under test that does *not* share a database connection with the
      # specs, so use truncation strategy.
      DatabaseCleaner.strategy = :truncation
    end
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.append_after(:each) do
    DatabaseCleaner.clean
  end

end


まとめ

今日、職場のプログラムでcapybaraテストを実行することについに成功した!結果から言うと、ある小さなエラーのせいでほかの部分もうまくいっていなかったということだった。実につまらないもののせいでつまづいたなと思ったね。次はもっと気を付けていこうと思う。


ご精読ありがとうございました。では、また次回まで✌





Day 17はこちら↓↓
programming-shop.hatenablog.com

Ruby on Rails開発のインターン (Day 17)

こんにちは、皆さん!

今日はついに実際に使っているマップにテストを書いていこうと思う。ここまではずっとcapybaraテストを勉強する用のアプリに書いてきた。さあ、ここから習ったものを使って実際に使用するものに反映していこう。


  • トピック:
  1. capybaraテストでCSSの値にアクセスする方法
  2. capybaraテストでJavaScriptを実行する方法


  • 疑問:


  • 問題:


  • 学習した内容:
  1. capybaraテストからCSSの値を引き出す方法
  2. Rubyでsubstringする方法
  3. capybaraテストでJavaScriptを実行する方法
  4. マップ上のすべてのマーカーを返してくれる関数はないので、マーカーを足すときに配列などどこかにそのコピーを持っておいてそこからマーカーにアクセスできる


  • 今後やってみたいこと:


  • リソース:
  1. The Basics of Capybara and Improving Your Tests — SitePoint


capybaraテストでCSSの値にアクセスする方法

マップの横幅を使い、どんな大きさのマップにも対抗できるテストを書こうとした僕はcapybaraテストの中からCSSの値をとる必要があった。それで、調べてみて、capybaraからCSSの値をとる方法を探し出した。

最初に、div#map(IDが"map"のdivタグ)にあるマップにアクセスしたかった。
それで、下記のようにアクセスした。

find('#map')

そして、次はそこからスタイルを取り出す方法。これに関しては全くリソースが見当たらなかった。

find('#map').style('width')

結構適当にあてずっぽうで行ったところもあるが、これでスタイルにアクセスすることができた。
style.widthのようにドットとスタイル名でアクセスするJavaScriptとは違って、スタイル名を()の中に入れる。
それを変数に入れて、後で使う。

map_width = find('#map').style('width')

とここで、うまくいかなかったので、とりあえず、この変数の内容をアウトプットしてみた。驚くことにHashだったのだ。

{"width"=>"400px"}

ということで、改めて、実際の値を取り出す方法をHashのやり方に変えた。map_width['width']みたいに。
ここまででも、なかなか複雑だが、さらに、面倒くさいことに得られた値には"px"がついているので、数字として運用するにはさらにこれを取り除く必要がある。

# 横幅のHashにアクセス
map_width_hash = find("#map").style("width")
# 横幅の値の文字列版を入手
map_width_string = map_width_hash['width']
# 数字の値にするためにpxをカットして、そのあとにそれをintegerに変換する
map_width = map_width_string[0..(map_width_string.length-2)].to_i

ちなみに、ここでRubyにおいてどうやってsubstringをやるのか学んだ(笑)

capybaraテストでJavaScriptを実行する方法

たまにcapybaraテストの中でJavaScriptを使いたくなることがある。例えば、僕のケースだとマップの中心を他の地点にするとき。これはマップオブジェクトへのアクセスがないと成立しないし、肝心のマップオブジェクトはRubyからはアクセスできない。そんなとき、JavaScriptを使ってそこに作用する必要があるのだ。

やり方は簡単。下記のような関数をcapybaraテストの中に入れればよい。

page.execute_script("example('Hello')")

この例だと、"example"という名前の関数を'Hello'という引数を入れたものを実行する。

***ひとつ大事なことは実行したいJavaScriptのコードがcapybaraテストで訪れるサイト内でアクセスできるようにしなければならないということ!! 僕の場合は直接map.html.erbに入れた。(パイプラインを使っている人は大丈夫だと思う)***

まとめ

今日はいい日だった。少しコードを書いて、それのおかげでcapybaraが複数のマーカーを自動でクリックしてくれた。ライブでそのマーカーの一つ一つをめぐるのを見た時はかなり満足していたし、そのアプリがクールに見えた。
結局、職場のプログラムでcapybaraテストによるマップのテストはまだうまくいかなかったが、最終的なアイデアをしっかりコード化できた。
本当のマップは少しばかり複雑なので、もう少しコードを書くのに時間がかかりそう。うまくここまでやってきたコードが直結するといいな。


ご精読ありがとうございました。では、また次回まで✌



Day 18はこちら↓↓
programming-shop.hatenablog.com


Day 16はこちら↓↓
programming-shop.hatenablog.com

Ruby on Rails開発のインターン (Day 16)

こんにちは、皆さん!

今日はどうやったらグーグルマップ上でマーカーをクリックするのかを見つけようと思う。これは以前のに比べれば、そんなに難しくはないだろうと思うが、後でマーカーから出た情報をもとにテストを書くのに少し時間がとられる気がする。あんまり時間を取られすぎなければいいが。


  • トピック:
  1. capybaraでスクショをとる
  2. capybara-screenshotジェムを使ってより簡単にスクショ機能を実装する方法
  3. 僕がcapybaraでグーグルマップ上のマーカーをクリックさせた方法


  • 疑問:


  • 問題:
  1. capybaraでグーグルマップ上のマーカーをクリックする方法を探す


  • 学習した内容:
  1. capybaraで自動でスクショを取る方法


  • 今後やってみたいこと:


  • リソース:
  1. Testing Your App In The Browser With Capybara (Rails Backend, React Frontend)
  2. GitHub - mattheworiordan/capybara-screenshot: Automatically save screen shots when a Capybara scenario fails
  3. How can I click on a google map with capybara to create a marker - Stack Overflow


capybaraでスクショをとる

リソース: Testing Your App In The Browser With Capybara (Rails Backend, React Frontend)

僕が試しに直接page.save_screenshot('screenshot.png')というコードをposts_controller_spec.rb内で実行しようとしたら、失敗して、下記のエラーメッセージが出てきた。

     Selenium::WebDriver::Error::WebDriverError:
        Unable to find Mozilla geckodriver. Please download the server from https://github.com/mozilla/geckodriver/releases and place it somewhere on your PATH. More info at https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/WebDriver.

それで、このサイトにある指示通り、インストールしたのち、 今度はこの

$ export PATH=$PATH:/usr/local/bin/
$ whereis geckodriver
geckodriver: /usr/local/bin/geckodriver



ここまで設定ができたら、capybaraテストを実行したときに、URLの左側にロボットのマークが表示されるはず。これはロボットが自動でそのページに指定された行動をとることを表す。そして、私たちはその一連の動作をこのページでライブで見れるということだ。

そして、そのデモが終わると、スクショが/tmp/capybara/screenshot.pngで見つかるでしょう。このフォルダーは.gitignoreでネット上には送られないようになっているので、心配無用。(まあ、でも、逆に見つけにくかったけど笑)


僕は下記のコードで実行して、クリックした後にボタンの内容が"Thank you"に変わるというコード。

<div id="map" style="width: 400px; height: 400px;"></div>

<button id="button" onclick="changeContent()">Click Me!</button>

<%= javascript_tag do %>
    function initialize(){
        var map_center = new google.maps.LatLng(51.5, -0.12);
        var map = new google.maps.Map(document.getElementById('map'), {zoom: 15, center: map_center});
        var center_marker = new google.maps.Marker({position: map_center, map: map});
        var info = "<p>Success!</p>";
        var infowindow = new google.maps.InfoWindow({
            content: info
        });
        center_marker.addListener('click', function(){
            infowindow.open(map, center_marker)
        });
    }
    function changeContent(){
        document.getElementById('button').innerHTML = "Thank you";
    }
<% end %>

下のは実際にcapybaraに撮られたscreenshot.png。"Click Me!"が"Thank you"になっているのが確認できる。よって、テスト成功である
f:id:Coding_Studio:20180726045704p:plain

capybara-screenshotジェムを使ってより簡単にスクショ機能を実装する方法

リソース: GitHub - mattheworiordan/capybara-screenshot: Automatically save screen shots when a Capybara scenario fails

ところで、もっと簡単にスクショを取る方法を見つけた。それはcapybara-screenshotジェムを使うことだ。使うためにはまず、Gemfileに下記のようにジェムを入れる。

gem 'capybara-screenshot', :group => :test

僕はRspecを使っているからここより先の内容はRspecを使う際のインストラクションになる。ほかの媒体を使う場合はこのサイトを参照にしてください。
そしたら、rspec_spec.rbの中に下記のを入れる (僕の場合、require 'capybara/rspec'を他のところからインポートしているが、下記のを入れるときは必ずrequire 'capybara/rspec'より下に入れてください。)

require 'capybara-screenshot/rspec'



そしたら、もうスクショをとるためのコードを書く準備は整った!
僕の場合は、下記のを古いバージョンのスクショと入れ替える感じでposts_controller_spec.rbに追加した。

Capybara.save_path = "app/assets/images"
Capybara::Screenshot.screenshot_and_save_page

1行目はスクショがどこに保存されるかで、2行目のコードでスクショを保存する。
そしたら、驚くことにスクショだけでなく、ディベロッパーツールで表示されるhtmlコードまでもがapp/assets/imagesに保存されていた。

僕がcapybaraでグーグルマップ上のマーカーをクリックさせた方法

最終的に、解決法を見つけることができた。ほとんどこのサイト通りのコードをコピーペーストしただけだった。僕がコピーしたのは下記の部分:

within_frame(locator_of_frame_with_map) do
  map = find(locator_of_map).native
  page.driver.browser.action.move_to(map, x, y).click.perform
end

まあ、でも、これはなぜだかわからないが残念ながらうまくいかなかったので、within_frameのくくりを消した。また、僕は下記のようにマップを実行しているから、

<div id="map"></div>

下記のようにルビーコードを書いた

  map = find('#map').native
  page.driver.browser.action.move_to(map, 200, 190).click.perform



説明はこうだ:

  • 1行目でマップオブジェクトにたどり着く。よって、2行目でマップに何かできる。
  • 2行目でマウスを(x, y)=(200, 190)のポイントに行かせた。これは400x400のマップの中心のやや上である。
  • この場所を選んだ理由はそこがちょうどマップの中心に位置するマーカーのクリックできるところであるからだ。
  • そして、その場所でcapybaraにクリックをさせる。これはつまりマーカーの詳細を表示するようにしたことになる。

最初はマップ内の座標を得ようと思ったが、できず、考えてみた結果、僕たちがマップ上にクリックするときだって画面の中心という感じでしか画面上のものをとらえることはできないから、このxとyの座標はすごく腑に落ちた。
以下がcapybaraテストの結果:
f:id:Coding_Studio:20180726083605p:plain


さらに、マップ上の複数のマーカーをクリックさせるという内容も実行した。解決法はいたってシンプルで、僕がマーカーオブジェクトにアクセスでき、そこからマーカーの位置を知ることができるから、マップの中心をその新しいマーカーの位置にずらすことで先ほどと同じ場所をもう一回クリックすればいいのだ。
下記のビデオにこの時、自動で複数のマーカーを1個ずつクリックしたものが記録されている。

CapybaraとRspecでGoogle mapのテスト!

まとめ

capybaraでマップ上のマーカーをクリックする方法を見つけることができたことがすごく嬉しかった。stackOverFlow上の人がサイト上の答えはちゃんと動かなかったと言っていたので、最初はとても心配した。まあ、でも、最終的に手に入れたかったものが自分の手で入ったので、大きな達成感を感じられた。
明日はこのcapybaraテストの内容を職場のプログラムに組み込めれるようにがんばりたい。明日もいいことありますように!!


ご精読ありがとうございました。では、また次回まで✌



Day 17はこちら↓↓
programming-shop.hatenablog.com


Day 15はこちら↓↓
programming-shop.hatenablog.com

Ruby on Rails開発のインターン (Day 15)

こんにちは、皆さん!

今日もまた天気のいい日。今日はcapybaraテストのシンタックスを勉強して、本題に入れるようにがんばる。


  • トピック:
  1. Capybaraテストの基本フレーム
  2. いくつかの基礎的なcapybaraテストのシンタックス


  • 疑問:


  • 問題:
  1. グーグルマップにおいて、capybaraでマーカーをクリックする


  • 学習した内容:
  1. どうやって簡単なcapybaraテストを書くか


  • 今後やってみたいこと:
  1. capybaraでスクショをとる


  • リソース:
  1. Ruby for Newbies: Testing Web Apps with Capybara and Cucumber - YouTube


Capybaraテストの基本フレーム

リソース:Ruby for Newbies: Testing Web Apps with Capybara and Cucumber - YouTube

capybaraテストに関するビデオチュートリアルを発見(残念ながら、英語版)。それの内容を参考に下記が基礎的なフォームになる。

# spec/features/test_spec.rb

require 'rails_helper'
RSpec.feature "test" do
    scenario "test whether you can write out a proper test" do
         # your code here
    end
end

実際のテストに入る前にrails_helperする必要がある。 それと、通常、capybaraテストはspec/featuresフォルダー内でファイルを作り、そこに書いていく。

いくつかの基礎的なcapybaraテストのシンタックス

以下がこのブログで使ったリンク↓↓
https://github.com/Eric1015/capybara-post-test
それで、書いたコードは下記のもの:

# spec/features/posts_controller_spec.rb

require 'rails_helper'
RSpec.feature "adding post" do
    scenario "allow a user to add a post" do
        #パート1
        visit posts_new_path

        #パート2
        fill_in "Title", with: "Rspec Introduction"
        fill_in "Body", with: "This is my post about Rspec"

        #パート3
        click_on("Create Post")

        #パート4
        expect(page).to have_content("Rspec Introduction")
        expect(page).to have_content("This is my post about Rspec")
    end
end



さあ、掘り下げていきましょう!!
最初に、visit posts_new_pathはその名の通り、 指定したURLに行くってこと。この場合、/posts/newになる。
下の写真はこのページのスクショ。
f:id:Coding_Studio:20180725044212p:plain
見ての通り、"Title"と"Body"の2つのインプットがある。


次の部分はその2つのインプットに"Title"には"Rspec Introduction"を、そして、 "Body"には"This is the first post about Rspec"を入れる。これはつまり、下の写真通りのことを自動でやってくれるってこと。
f:id:Coding_Studio:20180725044611p:plain


そして、3つ目のパート、click_on("Create Post")は"Create Post"というボタンを押してくれる。これはインプットした情報をもとに新しい投稿を作る(ポストというモデルを使用しているため)。その後、showアクションをとるようにしているため、 下記のような結果になる。
f:id:Coding_Studio:20180725044840p:plain


そして、最後のパート。ここで、初めてテスト(ここまではcapybaraにユーザーが実際に投稿を作る一連の操作をさせただけ)。テストの内容は今現在のページに2つのものが存在すること。それは、"Rspec Introduction"というテキストと"This is my post about Rspec"というテキスト。そして、確かにshowのページにこれらがあるため、無事にテストは成功という結果になる。
f:id:Coding_Studio:20180725045728p:plain

まとめ

capybaraテストの基礎を学べていい感じになったので、本題に入り、capybaraを書いていこうと思った。でも、それで始めて見ると、なぜか職場のプログラムではcapybaraテストが実行されなかった。何時間か原因解明に努めたが結局はわからず。
とりあえず、明日は次のステージであるマップ内のマーカーのクリック方法を探っていこうと思う。早く方法を見つけれることを願う!


ご精読ありがとうございました。では、また次回まで✌



Day 16はこちら↓↓
programming-shop.hatenablog.com


Day 14はこちら↓↓
programming-shop.hatenablog.com

Ruby on Rails開発のインターン (Day 14)

こんにちは、皆さん!

ゲーム漬けの週末が終わり(マジでずっとPUBG遊んでた笑)、4週間目が始まった。
今日は新しくデザインを変更するマップページで自分に何ができるかを見つけて作業に取り掛かれたらなって感じ。


  • トピック:
  1. capybaraとは何か?


  • 疑問:


  • 問題:
  1. capybaraでグーグルマップをテストする方法を探す
  2. 職場のプログラムにおいて、capybaraテストが何らかの原因で実行できない


  • 学習した内容:
  1. capybaraテストを使えば、クリックやフォームの記入といった様々なユーザーのとる行動を自動でプログラムで試すことができる


  • 今後やってみたいこと:
  1. capybaraテストに関する面白いチュートリアルを作る


  • リソース:
  1. GitHub - teamcapybara/capybara: Acceptance test framework for web applications
  2. Full-Stack Testing with Rails System Tests
  3. GitHub - learn-co-curriculum/intro-to-capybara


capybaraとは何か?

capybara(キャピバラ)と聞いて、まず頭になにが浮かびますか?
普通ならこれだよね↓↓
f:id:Coding_Studio:20180724072015j:plain


まあ、僕が紹介したいのはRailsにおけるcapybara(キャピバラ)なので、こっちが正しいね。
f:id:Coding_Studio:20180724072515p:plain


capybaraはジェムの一つでボタンのクリックやフォームの記入、ページを訪れるなどのユーザーがとる行動を再現して同じことをプログラムで試すテストを書くためのものだ。これはとても便利な機能で、実際にユーザーがたどるシナリオを想定してそれがうまくいくかを試せるシュミレーターのようなものなのだ。
***この種のテストはよく耳にする単体テストとは異なる***


このサイト上の下記の写真が分かりやすい。(一番上の層)
f:id:Coding_Studio:20180724080647p:plain


しかし、このようなテストはコードは書きにくいし、考えられるシナリオはいくつもあるのでとてもコストのかかるもの。その中で、いったいどういうシナリオをテストすべきなのかをしっかり判断しなければならない。
このサイト上の下記の写真からもわかるようにすべてのテストに占めるcapybaraテストの割合は少ないが、そのコストは高く、時間を取られる。
f:id:Coding_Studio:20180724082153p:plain

まとめ

今日は何時間かシニアのディベロッパーとどうやってマップをテストするのかに関して議論しあった。この新しいマップはいくつかプログラミングが絡んでくる機能がついているから、それらの機能がしっかり動いているのか確認するテストを書く必要がある。簡単に言うと、マップ上のマーカーをクリックするときにその機能が主に使われる。だから、これを可能にしてくれるテストの方法を探す必要がある。明日は手段を早いうちに見つけて、コードを書く作業に移れるといいな。


ご精読ありがとうございました。では、また次回まで✌



Day 15はこちら↓↓
programming-shop.hatenablog.com


Day 13はこちら↓↓
programming-shop.hatenablog.com

Ruby on Rails開発のインターン (Day 13)

こんにちは、皆さん!

この前、Heroku上でTuneMyGCを使ってみることを提案したから、ここからはメモリリーク以外のことをやっていけると思う。それで、任されたのはグーグルマップの更新。もともとサイト内にマップはあるのだが、デザインと機能を一新するので、いろいろとやることが出てきた。


  • トピック:
  1. Railsにおけるグーグルマップ
  2. geocoderとは?
  3. どっちの方が近いのか調べる


  • 疑問:
  1. グーグルマップをGmapで実行した方がプレーンのJavaScriptより良いことはあるのか?


  • 問題:


  • 学習した内容:
  1. グーグルマップAPIの登録の仕方
  2. 2点間の距離を計算する方法


  • 今後やってみたいこと:
  1. 自分のサイトにもグーグルマップを組み込んでみる


  • リソース:
  1. GitHub - apneadiving/Google-Maps-for-Rails: Enables easy Google map + overlays creation in Ruby apps
  2. Latitude and Longitude Finder on Map Get Coordinates
  3. Geocoder: Display Maps and Find Places in Rails — SitePoint
  4. GitHub - alexreisner/geocoder: Complete Ruby geocoding solution.


Railsにおけるグーグルマップ

Railsでは、普通のHTMLウェブサイトでグーグルマップを実行する方法とRails特有のジェムを使う方法の両方が使えるようだ。
Rails専用のジェムに関しては下記のサイト通りにやればいいみたい(僕はHTML型で実行する方が好きになった)。
GitHub - apneadiving/Google-Maps-for-Rails: Enables easy Google map + overlays creation in Ruby apps


それで、当然のようにAPIキーをこれまた要求されるので一つ作りましょう!
こちらのサイトからAPIキーは手に入れられる。
Google Cloud Platform
このサイトでは、更にAPIキーを利用できるサイトの制限をURLを指定してできるため、安全にAPIキーを利用可能。


このトピックに関する内容はかなりの量のため、ここでは触れないでおく。いづれチュートリアルという形でまとめていきたいと考えている。

geocoderとは?

Resource: GitHub - alexreisner/geocoder: Complete Ruby geocoding solution.

geocoderRailsではジェムの一つで緯度と経度の処理をしてくれる優れもの。ジェムをインストール後、そのクラスで定義された様々な便利な関数を利用することができる。
そのジェムをインストールするには下記をGemfileに入れる。

gem 'geocoder'

そしたら、いつも通りbundle install
これで、先ほど述べた便利な関数へのアクセスを確保できた。ここでは、その中の一つ、距離を緯度と経度から計算するものについて、少し紹介したい。

どっちの方が近いのか調べる

距離を計算するためには、以下の関数に2点のそれぞれの緯度と経度を当てはめればよい。

Geocoder::Calculations.distance_between([lat1, lon1], [lat2, lon2])

じゃあ、例えば東京から韓国のソウルまでの距離と大阪からソウルまでの距離を比べてみたいとしよう。
そしたら、それぞれの緯度と経度を入手するためにまずこちらのサイトへ↓↓
Latitude and Longitude Finder on Map Get Coordinates
このサイトで以下の写真のように都市名を入力したら、その後その写真内の数値が得られた。
f:id:Coding_Studio:20180721063213p:plain
f:id:Coding_Studio:20180721063218p:plain
(あ、もし、新宿と大阪市役所が東京と大阪の中心であるとするこの定義に異議ありなら、ぜひグーグルに連絡ください笑)


ここから僕はコンソールでルビーコードを書いていく。
まず、コンソールを開くためにrails cとターミナルでたたく。 そしたら、どっちがソウル (lat: 37.566535, lon: 126.977969)に近いのかを計算するコードを打っていく

# define variables
2.2.2 :001 > seoul = {latitude: 37.566535, longitude: 126.977969}
2.2.2 :002 > tokyo = {latitude: 35.689487, longitude: 139.691706}
2.2.2 :003 > osaka = {latitude: 34.693738, longitude: 135.502165}

# get the distance
2.2.2 :012 > distance_to_tokyo = Geocoder::Calculations.distance_between([seoul[:latitude], seoul[:longitude]], [tokyo[:latitude], tokyo[:longitude]])
 => 716.2062912249935
2.2.2 :013 > distance_to_osaka = Geocoder::Calculations.distance_between([seoul[:latitude], seoul[:longitude]], [osaka[:latitude], osaka[:longitude]])
 => 515.1855204674704

この場合、1つ目の距離の方が2つ目のより大きいので、大阪の方がソウルに近いということが分かる。
つまり、ソウルに行くなら大阪からってことだね(笑)

まとめ

今日はいくつかグーグルマップの基礎的な捜査について学ぶことができた。この系の内容が簡単じゃないのは事実だが。新しいことがいっぱいあるので、どれとどれがどうつながるのかなどの辺はしっかり判別できるようにしていきたい。また、geocoderとgmapsは異なるものであることも学んだ(最初はgeocoderでマップを表示しようと思っていた笑)。
次の日にはもっと深くいろんな関数を掘り下げていこうと思います!!


ご精読ありがとうございました。では、また次回まで✌



Day 14はこちら↓↓
programming-shop.hatenablog.com


Day 12はこちら↓↓
programming-shop.hatenablog.com

Ruby on Rails開発のインターン (Day 12)

こんにちは、皆さん!

今日は昨日直したばかりのHeroku上でTuneMyGCをテスト。これで問題が解決できるといいが...


  • トピック:
  1. Railsで404と500エラー時のレイアウトを編集する
  2. Herokuでメモリ使用量を確認する


  • 疑問:


  • 問題:


  • 学習した内容:
  1. 自分のエラーページを作る方法
  2. Heroku上でメモリ使用量を見る方法


  • 今後やってみたいこと:


  • リソース:
  1. Dynamic Rails Error Pages | mattbrictson.com


Railsで404と500エラー時のレイアウトを編集する

ウェブサイトを転々としているとたまに404または500エラーと書かれたページにたどり着くことがあるかと思う。デベロッパーなら、その時のレイアウトも構築したいもの。


最初にまず、エラーが発生したときにRailsの中では何が起きているか説明させてください。例えば、404エラーが発生したとしよう。そしたら、ウェブサイトは/404にリダイレクトしようとする。よって、Railsは'/404'がconfig/routes.rbの中にないか探し始める。つまり、僕たちがやるべきことはそのページを作り、config/routes.rbを編集し、そこに行かせればいいのだ。


では、実際の作業に移りましょう!
まず、下記のコマンドでエラーページを処理してくれるコントローラーを作りましょう。

$ rails generate controller errors not_found internal_server_error

次にすることはコントローラーの関数を書くこと。しかし、エラーを処理する際の関数は普通のと少し違う。

class ErrorsController < ApplicationController
  def not_found
    render(:status => 404)
  end

  def internal_server_error
    render(:status => 500)
  end
end

見ての通り、ステータスを明白にしなくてはいけない。これはこの2つのケースがデフォルトのステータスである'200'ではないので、しっかりコントローラーに伝える必要があるというからだ。
次に、コントローラーのポイントする場所を明示する。これはこれまでとそんなに変わらない。

match "/404", :to => "errors#not_found", :via => :all
match "/500", :to => "errors#internal_server_error", :via => :all

デフォルトでは、エラーページはpublic/フォルダーの中にある。そこに404.html500.html があるのが確認できることでしょう。
しかしながら、今は自分で設定したページに変更したいので、下記のラインをRailsconfig/application.rbファイルに追加して設定を変更しましょう!

# Application class
config.exceptions_app = self.routes

この設定の変更により、エラーが発生したとき、Railsはもともとのpublicフォルダーで探すのだが、見つからなかった場合、config/routes.rbで探すという設定を追加したことになる。

public/404.htmlpublic/500.htmlを削除する

これでエラーが発生したときに先ほど作成したページに行くようになる。つまり、404の時はapp/views/errors/not_found.html.erbを、500の時はapp/views/errors/internal_server_error.html.erbを表示するようになる。

  • Before:

f:id:Programming_Shop:20180728082938p:plain

  • After:

f:id:Programming_Shop:20180728083001p:plain

Herokuでメモリ使用量を確認する

ここまで、僕はずっとローカルでメモリの使用量を見てきた。けど、Heroku上でのメモリ使用はそれと違うから、そちらも確認したい。ここでは、どのようにHeroku上でのメモリ使用量を確認するかについて紹介する。


最初にHerokuでメモリ使用量をみれるように設定を変更する。ターミナルで下記のコマンドをたたくことで達成!

$ heroku labs:enable log-runtime-metrics

Herokuに反映させるために一度Herokuをリスタートさせる。

$ heroku restart

この後、Herokuのログをheroku logsで出すと、下記のようなメッセージが見られるでしょう。

2018-07-19T22:08:53.002898+00:00 heroku[web.1]: source=web.1 dyno=heroku.101841384.9d514caa-3366-4316-9647-fe2806ee7203
sample#memory_total=242.52MB sample#memory_rss=242.51MB sample#memory_cache=0.01MB sample#memory_swap=0.00MB 
sample#memory_pgpgin=62376pages sample#memory_pgpgout=291pages sample#memory_quota=512.00MB

この場合、僕はsample#memory_totalからわかる通り、242.52MBのメモリを使用していることになる。


また、heroku logs -tコマンドでライブでHerokuのログを確認することもできる。


もし、月に7ドル払うことで、Hobby dynosを使用することができ、おまけに下記のようにHeroku上のメモリ使用状況のグラフが見れる。
f:id:Coding_Studio:20180721025502p:plain

まとめ

今日は少し時間があったので、職場のルビーコードをより深く掘り下げてみた。それで学んだのがエラーページの処理の仕方を学んだ。明日は次に修正するマップを掘り下げていきたいなと思っているところ。


ご精読ありがとうございました。また次回まで✌





Day 11はこちら↓↓
programming-shop.hatenablog.com