Ruby on Rails開発のインターン (Day 27)
こんにちは、皆さん!
7週目がやってきた。インターンも残りわずかだ。もうあと2週間だから時間も限られている。今やっているマップテストをどこまでやるべきなのかもよくわからない。思い返すと、このインターンはすごくよかったし、思っていたよりずっと短かった気がする。時間がたつのって本当に早いね(笑)
- トピック:
- 疑問:
- 問題:
- 学習した内容:
- テストが始まる前に変数をあらかじめ定義する
- 今後やってみたいこと:
- リソース;
テストで使われる変数をあらかじめ定義する
テストでこの機能を使おうと思ったのは、多くのシチュエーションがあり、それぞれに対するマーカーが必要だし、いくつかのテストで同じものを使いたいと思ったからだ。
少し探してみたら、下記のようなテンプレが出てきた
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
これで僕の場合はうまくいき、同じ変数の定義を避け、コードがずっとよく見えるようになった。
まとめ
ご精読ありがとうございました。では、また次回まで✌
Ruby on Rails開発のインターン (Day 26)
こんにちは、皆さん!
今日のフォーカスはどうやってCapybaraテストからコントローラー内のインスタンス変数にアクセスすることができるかだ。それと、今日の朝、新たなウェブサイトのベースを作らないかと相談されたので、内容の少ない比較的新しいウェブサイトを作る機会があるかもしれない。
- トピック:
- 疑問:
- 問題:
- Capybaraテストからコントローラー内のインスタンス変数にアクセスできない(代わりの方法で解決)
- 学習した内容:
- 今後やってみたいこと:
- リソース:
コントローラーの変数を使う代わりに
僕がやったことはとても基本的なことで、テストコードを書いているファイル、つまり、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
というセクションを開いて、Network
セクションの真下にあるPreserve log
というものをクリックした。
そして、彼はウェブサイトをリロードして、そのツール上で下記のような内容のものが出てきた。
これはどのページがどのHTTPリクエストでプロセスされたのか教えてくれるため、エラーがどこにあるか見つけるときに役立つ。
そして、そのリンクにクリックすると、HTTPリクエストの詳細を表示してくれる。
これのおかげで、無事エラーがどこで発生しているかわかり、今のサイトがPOSTリクエストを出したが、失敗したのが分かった。つまり、これでこのサイトが定義されていない"/groups"というPOSTリクエストをしようとしたことが分かる。
まとめ
毎日何がしたいのかというリストなどを作り、日々しっかり管理する必要がある気がする。じゃないと、やりたいことが多すぎて、結局大事な次のものが始めれなくなっちゃう気がする。よい管理方法を見つけれるといいな。
ご精読ありがとうございました。では、また次回まで✌
Ruby on Rails開発のインターン (Day 25)
こんにちは、皆さん!
今日は問題なく動いているAPI キーを使う許可を取ろうと思う。そう簡単に一個くれるのかどうかはよくはわからないが。代わりの何かの手段を提案してくると予想しているが、とにかくこの問題にもうちょっとちゃんと取り組んでほしいなと思う。じゃないと、先に進めないし。
- トピック:
- 疑問:
- 問題:
assign
関数が使えない
- 学習した内容:
- テスト時にコントローラー内のインスタンス変数を直接使うことができなく、いくつかの関数を使う必要がある
- 今後やってみたいこと:
- リソース:
rails-controller-testing
ジェムでテスト時にコントローラー内のインスタンス変数にアクセスする
少しネットで探してみると、rails-controller-testing
というジェムを使うべきだそう。その後、下記のようにassigns
関数を使うことでインスタンス変数にアクセスするそう。
assigns(:markers)
しかしながら、これに関して、僕の場合はNo method defined assigns function
というエラーが返ってきた。よって、またこの関数について詳しく探っていかないといけないという感じだね。
まとめ
ご精読ありがとうございました。では、また次回まで✌
Ruby on Rails開発のインターン (Day 24)
こんにちは、皆さん!
今日はいろんな方法試してマップ上にマーカーを追加してみようと思う。いいの見つけれてやることリストの次のものに移れるといいな。
一方で自分のウェブサイトも作っているのでそちらも早くやりたいな。だから、仕事を早く終わらせようというモチベーションにもなっている(笑)。
- トピック:
- 疑問:
- 問題:
- GeocoderがAPIキーの問題があるのでデータベースにデータを追加できない
- 学習した内容:
- punditジェムを使って見やすいコードのままユーザーのアクセス制限を行うことができる
- 今後やってみたいこと:
- 自分のアプリでpunditジェムを使ってみる
- リソース:
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の機能を使う
例えば、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キーの問題への解決策が見当たらなければ、彼らのキーを使わせてもらえるように呼び掛けてみようと思う。
ご精読ありがとうございました。では、また次回まで✌
Ruby on Rails開発のインターン (Day 23)
こんにちは、皆さん!
長い週末が終わり、また職場に戻ってきた。最近なぜかわからないが、マネージャーともう一人のディベロッパが全く連絡を取り合わないからやることリストも更新されていなくて、少し心配だ。すぐに対処してくれるといいが。
- トピック:
- 疑問:
- 問題:
- GeocoderがAPIキーの問題でデータベースにデータを足すのを拒否してくる
- 学習した内容:
- 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キーに登録しないといけないのかな?
今のところ、これへの対処法はわからないな。
ご精読ありがとうございました。では、また次回まで✌
Ruby on Rails開発のインターン (Day 22)
こんにちは、皆さん!
今日は同僚のインターンに来てる人が今日でラスト1日になるのでみんなとランチに行くことになっている。楽しみだな。
一方で、もうマネージャーの修正を待ってもいられないので、エラーになっている部分をコメントアウトして、自分の書いたコードをテストしていこうと思う(笑)。
- トピック:
- 疑問:
- 問題:
- 学習した内容:
- エラーページのレイアウトをコントロールするジェムが存在する
- 今後やってみたいこと:
- リソース:
Capybaraテストで
native
関数でCSSスタイルの値をより簡単に取り出す
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ステップを飛ばせるからコードを書くのを楽にしてくれるのだなと感じた。
まとめ
仕事に関しては、エラー部分を取り除いてテストを始めた。そして、テストコード中に修正する部分があるなと思ったので、それの修正もした。そして、今週最後の日であり、3連休が待っているので、しっかり休んでまた火曜日に備えるぜ!
ご精読ありがとうございました。では、また次回まで✌
Ruby on Rails開発のインターン (Day 21)
こんにちは、皆さん!
今日は引き続き、マップのバグの修正と最近のバグ修正で発生した新たなバグに取り掛かろうと思う。
- トピック:
- 疑問:
- 422エラーをわざと起こすにはどうしたらいいのか?
- 問題:
- アドミンとしてサインインしようとすると、422エラーが発生する
- 学習した内容:
- 422エラーの存在と曖昧だがその要因
- 今後やってみたいこと:
- リソース:
422エラーとは?
このサイトの情報が役に立つかもしれません↓↓
developer.mozilla.org
先に述べたエラーのほかに422エラーたるものが存在し、HTTPリクエストが正しく機能し、コード中の関数にも問題がないうえ、データ処理がうまくいかなかったときに起きるそうだ。ここまではあくまで予想だが、職場のアドミンサインインがうまくいってないのはデータベースに本来はない何かがどこかのタイミングで追加されたからではないかと思っているところ。とりあえず、どこで問題が起きているのかもよくわからないから解決もなかなかきついって感じだな。
追記***
後になって、環境変数の設定に問題があったのだと判明した。しかし、一気に環境変数を刷新したのでどの特定の環境変数が問題を起こしていたかまではわかっていない...。
まとめ
後は、マネージャーが早くエラーの確認をして、明日にはマップのテストに戻らせてくれればいいな
ご精読ありがとうございました。では、また次回まで✌