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

こんにちは、皆さん!

7週目がやってきた。インターンも残りわずかだ。もうあと2週間だから時間も限られている。今やっているマップテストをどこまでやるべきなのかもよくわからない。思い返すと、このインターンはすごくよかったし、思っていたよりずっと短かった気がする。時間がたつのって本当に早いね(笑)


  • トピック:
  1. テストで使われる変数をあらかじめ定義する


  • 疑問:


  • 問題:


  • 学習した内容:
  1. テストが始まる前に変数をあらかじめ定義する


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


  • リソース;


テストで使われる変数をあらかじめ定義する

すべてのテストで使われるし、コードがきれいに見えるからあらかじめ変数を定義するのはすごく役に立つ。

テストでこの機能を使おうと思ったのは、多くのシチュエーションがあり、それぞれに対するマーカーが必要だし、いくつかのテストで同じものを使いたいと思ったからだ。

少し探してみたら、下記のようなテンプレが出てきた

before(:each) do
  # your code here
end

それで、僕は下記のを試した

before(:each) do
  place = Place.find(1)
end

その後、テスト内でその変数を使おうとしたら、下記のようなエラーが返ってきた。

NameError:
       undefined local variable or method `place' for #<RSpec::ExampleGroups::TheSigninProcess:0x0055ddbc033078>

スペルミスはなかったのですごくおかしな感じがしたのだが、後になって、インスタンス変数しかこのような役割を果たすことはできないとわかった。つまり、あらかじめ定義しようとしている変数の前に@をつける必要があったのだ。よって、下記のが正しい。

before(:each) do
  @place = Place.find(1)
end

これで僕の場合はうまくいき、同じ変数の定義を避け、コードがずっとよく見えるようになった。

まとめ

それぞれのテストの前に変数を定義する方法について学んだ。この知識があれば、これからはもっと良いテストが書ける気がする。しかしながら、どうやったらもっと効率よく変数を定義することができるのかとまだ考えているところだ。一つのマーカーを作るのに、その中に入れるパラメータが多すぎて、一つ一回ずつでもかなりの手間だなと思った。何かいい方法を見つけれるといいな。


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



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


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

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

こんにちは、皆さん!

今日のフォーカスはどうやってCapybaraテストからコントローラー内のインスタンス変数にアクセスすることができるかだ。それと、今日の朝、新たなウェブサイトのベースを作らないかと相談されたので、内容の少ない比較的新しいウェブサイトを作る機会があるかもしれない。


  • トピック:
  1. コントローラーの変数を使う代わりに
  2. ChromeのディベロッパーツールのうちのNetworkというセクションを使う


  • 疑問:


  • 問題:
  1. Capybaraテストからコントローラー内のインスタンス変数にアクセスできない(代わりの方法で解決)


  • 学習した内容:
  1. ChromeディベロッパーツールのうちのNetworkを有効に使う一つの方法


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


  • リソース:
  1. ruby on rails - 'assigns' method not found in rspec capybara - Stack Overflow


コントローラーの変数を使う代わりに

この代わりとなる方法はどこかアホっぽいけど、どりあえず、問題を解決してくれる。
僕がやったことはとても基本的なことで、テストコードを書いているファイル、つまり、specファイルがルビーファイルであること。これって、つまり、コントローラーでやれることと同じことができる。だから、下記のようにマーカーを取り出すというコードに変更した。

@places = Place.all

なんとなく、面白く感じるのはこんな基本的なことに気づくまでに2,3日かかったってこと。もっと視界を広く持つべきだね。

以前、ブログで出したコントローラー内のインスタンス変数をアクセスするジェムはRails 5から消されたようだ。StackOverflowでその内容に言及したものがあった(英語版)。

Testing what instance variables are set by your controller is a bad idea. That's grossly overstepping the boundaries of what the test should know about. You can test what cookies are set, what HTTP code is returned, how the view looks, or what mutations happened to the DB, but testing the innards of the controller is just not a good idea.
- David Heinemeier Hansson

簡単に言うと、コントローラー内の変数にアクセスできるということはテストがしていいことの範囲を超えるそうだ。テストというのはそもそも決められたデータをテストするためにあるのであって、それに対する特定の値の一致が求められているのだ。

テストが何をし、どうやって機能しているのかを見直すいいチャンスだったと思う。こうやって、たまには基本に戻るべきだね。

ChromeディベロッパーツールのうちのNetworkというセクションを使う

これは僕のマネージャーが見せてくれたHTTPリクエストの種類をブラウザで確認する方法

彼はChromeディベロッパーツールを開いて、Networkというセクションを開いて、Networkセクションの真下にあるPreserve logというものをクリックした。
そして、彼はウェブサイトをリロードして、そのツール上で下記のような内容のものが出てきた。

f:id:Coding_Studio:20180811081947p:plain

これはどのページがどのHTTPリクエストでプロセスされたのか教えてくれるため、エラーがどこにあるか見つけるときに役立つ。
そして、そのリンクにクリックすると、HTTPリクエストの詳細を表示してくれる。

f:id:Coding_Studio:20180811082403p:plain

これのおかげで、無事エラーがどこで発生しているかわかり、今のサイトがPOSTリクエストを出したが、失敗したのが分かった。つまり、これでこのサイトが定義されていない"/groups"というPOSTリクエストをしようとしたことが分かる。

まとめ

久しぶりに確かに何かを学んだなと感じる一日だった。Chromeディベロッパーツールを軽く掘り下げたのがきっかけに僕はもうちょっとディベロッパーツールについて学んでみたいなと思った。このトピックに関してはかなり奥深いものがあるのではないかと踏んでいる。
毎日何がしたいのかというリストなどを作り、日々しっかり管理する必要がある気がする。じゃないと、やりたいことが多すぎて、結局大事な次のものが始めれなくなっちゃう気がする。よい管理方法を見つけれるといいな。


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



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


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

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

こんにちは、皆さん!

今日は問題なく動いているAPI キーを使う許可を取ろうと思う。そう簡単に一個くれるのかどうかはよくはわからないが。代わりの何かの手段を提案してくると予想しているが、とにかくこの問題にもうちょっとちゃんと取り組んでほしいなと思う。じゃないと、先に進めないし。


  • トピック:
  1. rails-controller-testingジェムでテスト時にコントローラー内のインスタンス変数にアクセスする


  • 疑問:


  • 問題:
  1. assign関数が使えない


  • 学習した内容:
  1. テスト時にコントローラー内のインスタンス変数を直接使うことができなく、いくつかの関数を使う必要がある


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


  • リソース:
  1. GitHub - rails/rails-controller-testing: Brings back `assigns` and `assert_template` to your Rails tests


rails-controller-testingジェムでテスト時にコントローラー内のインスタンス変数にアクセスする

Capybaraテストでコントローラー内のインスタンス変数を使いたくなる時がある。僕の場合は一つ一つのマーカーを回りたいのでそのマーカーたちが定義されているコントローラーのインスタンス変数にアクセスしたい。少なくともいくつマーカーがあるのかわかって、そしたら、マップの中心を何回動かせばいいのかわかるのでって思ったのだけど。

少しネットで探してみると、rails-controller-testingというジェムを使うべきだそう。その後、下記のようにassigns関数を使うことでインスタンス変数にアクセスするそう。

assigns(:markers)

しかしながら、これに関して、僕の場合はNo method defined assigns functionというエラーが返ってきた。よって、またこの関数について詳しく探っていかないといけないという感じだね。

まとめ

今日、ついにAPIキーの問題が解決した(しかし、いったいどこが原因でどうやって直したのかよくわからない。APIキーを変えたからかもしれない)。そして、それをクリアしたのち、初めて、Capybaraテストから直接コントローラー内のインスタンス変数にアクセスすることができないことに気づいた。明日からはこの問題について掘り下げていく。何か変数が使えるいい方法が見つかるといいな。


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



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


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

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

こんにちは、皆さん!

今日はいろんな方法試してマップ上にマーカーを追加してみようと思う。いいの見つけれてやることリストの次のものに移れるといいな。
一方で自分のウェブサイトも作っているのでそちらも早くやりたいな。だから、仕事を早く終わらせようというモチベーションにもなっている(笑)。


  • トピック:
  1. punditジェムのインストール
  2. punditの機能を使う


  • 疑問:


  • 問題:
  1. GeocoderがAPIキーの問題があるのでデータベースにデータを追加できない


  • 学習した内容:
  1. punditジェムを使って見やすいコードのままユーザーのアクセス制限を行うことができる


  • 今後やってみたいこと:
  1. 自分のアプリでpunditジェムを使ってみる


  • リソース:
  1. GitHub - varvet/pundit: Minimal authorization through OO design and pure Ruby classes


punditジェムのインストール

punditはすごくよく形成されたジェムであり、それを使って、編集ボタンが見えるかどうかなどのユーザーのアクセス制限を行うことができる。

punditを使うには、まず、下記のようにジェムをGemfileに入れる。

gem "pundit"

続いて、いつも通りのbundle install
そしたら、app/controllers/application_controller.rbに行き、下記のを入れる。

  include Pundit
  protect_from_forgery with: :exception

次に、ターミナルで下記のコマンドを実行する。

rails g pundit:install

これでいくつかの設定をセットアップしてくれるし、app/policiesも作成してくれる。

これで、基本的なセットアップは完了。

punditの機能を使う

では、実際にpunditの機能を使っていこう!!
例えば、Postというモデルがあったとしよう。これをPostを作ったユーザーのみがアクセスできるようにしたいとする。app/models/post.rbの中に下記のような1行が入っていることでしょう。(ユーザーがたくさんのPostを作るため)

belongs_to :user

なので、Postオブジェクトから@post.userのようにそれを作ったユーザーにアクセスすることができるでしょう。

ここで、一つapp/policies/post_policy.rbというファイルを作り、下記のようなコードを入れる。

class PostPolicy < ApplicationPolicy

  def initialize(user, post)
    @user = user
    @post = post
  end

  def edit?
    return true if @user = @post.user
  end

  def destroy?
    return true if @user = @post.user
  end

end

つまり、これらの関数は現在ログインしているユーザーがPostを作成したユーザーである場合のみTrueを返してくる。

そしたら、今度はapp/views/posts/show.html.erbに行き、下記のコードを追加する。

<%= link_to "Edit", edit_post_path(@post) if policy(@post).edit? %>
<%= link_to "Delete", destroy_post_path(@post) if policy(@post).destroy? %>

これが何を表すのかというと、先ほど述べたようにログインしているユーザーがPostを作成したユーザーでない限り、この2行の最後の部分はTrueにならない。だからif文もその時にしか成り立たない。なので、ログインしているユーザーがPostを作成したユーザーでない限り、この2つのボタンは表示されないということである。

まだまだpunditでコントローラーのアクセス制限を設定したりでき、より複雑だがきれいなコードを書くことができる。
この投稿でそこまではカバーできないが、Githubから参照してみてください。

まとめ

今日はまず、なぜAPIキーがエラーを返してくるのか他の人たちと議論した。シニアのディベロッパーとマネージャーの2人とも彼らのテストサイトでは普通に問題なく、実行されるそうなので、ますますなぜなのかわからなくなってくる。とりあえず、この件を彼ら2人に預けて僕はもう少しコードを見回してみた。punditジェムについて学べたのはいいことだったと思う。自分のウェブサイトを作っているところだから、このアクセス制限機能をうまくアドミンユーザーのために実行できればすごく良いものが完成する気がする。
明日になってまだAPIキーの問題への解決策が見当たらなければ、彼らのキーを使わせてもらえるように呼び掛けてみようと思う。


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



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


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

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

こんにちは、皆さん!

長い週末が終わり、また職場に戻ってきた。最近なぜかわからないが、マネージャーともう一人のディベロッパが全く連絡を取り合わないからやることリストも更新されていなくて、少し心配だ。すぐに対処してくれるといいが。


  • トピック:
  1. オートログアウトの仕組み


  • 疑問:


  • 問題:
  1. GeocoderがAPIキーの問題でデータベースにデータを足すのを拒否してくる


  • 学習した内容:
  1. Railsでオートログアウトを実行する方法


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


  • リソース:


オートログアウトの仕組み

通常セキュリティーの関係でユーザーがある程度の時間オフラインになったらアカウントからサインアウトするオートサインアウトを実行しているウェブサイトは結構ある。で、このRailsにおけるこれのやり方は意外にも普通の数学のように計算をして行われている。

最初にユーザーが戻ってきたときにその前にオンラインだったのが何分前なのかを知る必要があるからユーザーがオンラインになった時の時間をまずは記録する。下記のようにね。

session[:active_time] = Time.now

毎回ユーザーがオンラインになるたびにこの時間を更新するんだぞ

その後、ユーザーがアクティブになった時に下記のような計算をすることでいったいどれだけの時間がたったのかがわかる。

time = Time.now.to_time - session[:active_time].to_time

Time.nowはその時の時間を返してきてくれて、session[:active_time]は過去のユーザーがアクティブだった時間を返してくれる。つまり、この二つの値をもとに最後にアクティブだった時からどれだけ経ったのかを計算できる。

最後にすることは、これを自分の指定したい長さの時間と比べればよい。例えば、三十分後にオートサインアウトしてほしいのなら

if time > 30.minutes
  log_out
end


まとめ

テストしたときはマップはうまくいってないと思っていた。しかし、ローカルとテストで使われているマーカーの種類が違うだけでマップの中心に来るはずだと思っていたマーカーは元から存在していなかったのだ(笑)。
とりあえず、今、マーカーは問題ないことが分かったが、なぜかgeocoder曰く、APIキーにブロックされて新しいマーカーのデータをデータベースに足すことができない。
クレジットカードをAPIキーに登録しないといけないのかな?
今のところ、これへの対処法はわからないな。


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



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


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

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

こんにちは、皆さん!

今日は同僚のインターンに来てる人が今日でラスト1日になるのでみんなとランチに行くことになっている。楽しみだな。
一方で、もうマネージャーの修正を待ってもいられないので、エラーになっている部分をコメントアウトして、自分の書いたコードをテストしていこうと思う(笑)。


  • トピック:
  1. Capybaraテストでnative関数でCSSスタイルの値をより簡単に取り出す


  • 疑問:


  • 問題:


  • 学習した内容:
  1. エラーページのレイアウトをコントロールするジェムが存在する


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


  • リソース:
  1. GitHub - charliesome/better_errors: Better error page for Rack apps


Capybaraテストでnative関数でCSSスタイルの値をより簡単に取り出す

マップのテストのため、Capybaraテストのコードを書いていたとき、下記のようなコードでCSSのwidthのハッシュを以前やったように取り出した。

map_width_px = find("#map").style("width")

しかし、なぜか職場のプログラムだと下記のようなエラーが出てくるんですよね

NoMethodError:
   undefined method `style' for Obsolete #<Capybara::Node::Element>:Capybara::Node::Element

で、それで以前このようなコードの中に出てきたnative関数を使用してみた。そしたら、面白いことにこれでうまくいったというね。しかもよりいいと言うくらいのものだった。やったことは上記のコードを下記のようなものに変えただけ

map_width_px = find("#map").native.style("width")

これで僕の場合はうまくいき、さらに、便利なことにハッシュ(この場合、{"width": "400px"})ではなく、widthを直接返してくれた(この場合は、”400px”)
でも、結局上記のようなエラーが発生した理由はわからなかった。

とりあえず、このようなnative関数を使う形の運用はハッシュへのアクセスの1ステップを飛ばせるからコードを書くのを楽にしてくれるのだなと感じた。

まとめ

マネージャーと同僚たちとのランチはとてもよかった。レバノンのレストラン(もちろん初めて)に行ったのだが、何が有名なのか全くわからなかったわけなので、適当にオーダーした。初めてみんなとまともにしゃべるからであろう、会話はすごく充実していた。みんな生徒だったからってのもあったけど。そのうちの一人がトロント大学在学中の人だったことはそこで知った。この大学は僕がもともと行きたかった大学だった。いろいろとその大学で不便な部分が聞けて、結果的にUBCに来たのも悪くないなって思った(笑)。
仕事に関しては、エラー部分を取り除いてテストを始めた。そして、テストコード中に修正する部分があるなと思ったので、それの修正もした。そして、今週最後の日であり、3連休が待っているので、しっかり休んでまた火曜日に備えるぜ!


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



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


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

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

こんにちは、皆さん!

今日は引き続き、マップのバグの修正と最近のバグ修正で発生した新たなバグに取り掛かろうと思う。


  • トピック:
  1. 422エラーとは?


  • 疑問:
  1. 422エラーをわざと起こすにはどうしたらいいのか?


  • 問題:
  1. アドミンとしてサインインしようとすると、422エラーが発生する


  • 学習した内容:
  1. 422エラーの存在と曖昧だがその要因


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


  • リソース:
  1. 422 Unprocessable Entity Explained - KeyCDN Support


422エラーとは?

よく見かけるエラーといえば、404と500だから、このエラーは頻繁には見かけないでしょう。

このサイトの情報が役に立つかもしれません↓↓
developer.mozilla.org

先に述べたエラーのほかに422エラーたるものが存在し、HTTPリクエストが正しく機能し、コード中の関数にも問題がないうえ、データ処理がうまくいかなかったときに起きるそうだ。ここまではあくまで予想だが、職場のアドミンサインインがうまくいってないのはデータベースに本来はない何かがどこかのタイミングで追加されたからではないかと思っているところ。とりあえず、どこで問題が起きているのかもよくわからないから解決もなかなかきついって感じだな。

追記***

後になって、環境変数の設定に問題があったのだと判明した。しかし、一気に環境変数を刷新したのでどの特定の環境変数が問題を起こしていたかまではわかっていない...。

まとめ

今日は生産性の低い一日だったな。昨日の新しい機能の実装に伴うテストを終えてからというもの、何も次に何をやるのか示されていなく、またコードの中で気になるものを探していた。しかし、こんなことしてるとやっぱり、何もやってない気がして、罪悪感というか非充実というかそんな感じの思いに絡まれる。
後は、マネージャーが早くエラーの確認をして、明日にはマップのテストに戻らせてくれればいいな


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



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


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