SakuraWi - BLog

みんなのウェディングのエンジニア。聴いたお話をまとめておく倉庫的な。スタックストックスタック!

【Ruby on Rails】be_falsyとbe_falseyとbe falseの違いについて【RSpec】

Ruby on RailsのテストをRSpecで書いているみなさん、どうも櫻井広大です。

be_falsy使っていますでしょうか。

タイトルにもある、

be_falsy

be_falsey

be false

の違いについて書きます!


  • RSpecでfalseやtrueの返り値のマッチャ be_falsy ということで、結論から書きますと、

be_falsybe_falsey は同じです。

be_falsybe false違います。

僕は完全にすべて同じものだと思っていました。

  • be_falsyとbe_falsey

これはエイリアスによって同様のふるまいをするようになっています。

完全に好みで使うことができます。

  • be_falsyと be falseの違い これらは明確に違います。

実際によくあるテストコードはこんな感じですよね

it { is_expected.to be false }

で、これは明確に意味が違います。

be_falsy は、falsenilの場合にマッチするのです。

rubyでいうところの、falsyな振る舞いをするもの、つまりfalseとnilなわけなのです。

if文などで評価される時にも、rubyはfalseとnilではif文の中のブロックは実行されません。

厳密にマッチさせるのであれば、be falseeq falseでマッチャを書く必要があります。

個人的には、be falseのように記述する方が厳密なテストになるのでこちらの方がいいかなーと思います。

特に、 false || nilなどのようなふるまいのテストを書く場合に、意図せぬ挙動になる場合があります。

nilが返ってほしい場合とfalseが返ってほしい場合、その違いはあるのでしっかりと自分が意図した内容のテストになっているのかは見定めましょう。

2018年を振り返る

ということで、年の瀬も近くなってまいりましたので、今年の振り返りをしておこうと思います。

ざっくりこんなことできたよ、できなかったよ、これ楽しかったよを紹介します。

新卒2年目、櫻井広大の1年はこんな感じでございました。 一緒にいれてくれた人たち、ありがとう。

ふりかえり。

まずはgoogle photoとかいう神写真ツールを使って、今までの写真をみながら何があったかーなんてことを振り返ってみようかな、と。

せつさん家 いつもお世話になっている僕のメンター(と思っている)せつさん家。今年も5回くらいは行きました。 年明けていきなり何度かお邪魔しているみたい。

地球防衛軍5プレイ ゲームってなんだかんだ大事だなーと。協力ゲーで楽しい。ゲームやる時間がないってのはダメだなと。

VAZにお邪魔したり。 f:id:Saku-Saku:20181230223857j:plain

シズラーの発見 シズラーでソフトクリームを食べるのが最高。

バーフバリ インドの壮大さ。インド好き。笑

チャリタビ表参道編 f:id:Saku-Saku:20181230224542j:plain

キックボード通勤 あまりの徒歩嫌さ加減に、キックボードで通勤してみた。 なんかしんどいので、やめた。

髪の毛をあげるスタイルに なんか、伸びたからやめた

タピ活 以前からタピオカ好きだったので、広がるタピオカについていこうと必死。増え過ぎ。

伊達眼鏡かった あんまりつけなかった。と思ったら結構つけてた。 f:id:Saku-Saku:20181230224937j:plain

lineモバイルにした。 これはかなりよかった。誰か変更したい人がいたら、ぜひ声をかけて。

シンガポールへ f:id:Saku-Saku:20181230224139j:plain

メルチャリへ乗るためだけに福岡に。

HADOプレイ

switch会 何度か家に友人を招いてゲームする時間をつくった。

香港へ f:id:Saku-Saku:20181230230206j:plain

スケボやってみた もうあんまりやっていませんね。。

なぞの間接照明買う。

貴族会っていういい飯食べる会 2会ほど。 ASOとか

macを新調 f:id:Saku-Saku:20181230230536j:plain

わがやにエモみが? f:id:Saku-Saku:20181230230647j:plain

ブロックチェーンハッカソン参加

大学友人会

zozo定期便試す

ミッドタウン日比谷のデザートが日本トップレベルでうまいことに気づく

万引き家族みた。

いろんなメンバーで朝活

ディズニーランドGO。 ディズニーあんまりいったことないけど超楽しかった。

韓国へカジノ体験

BBQ大会

ナース酒場 in カルカル

メダカつかまえる

机購入 家具を買うというのはいいことだという気づき。

わんこそば

ジェットヲォッシャードルツが残念。

nohanaとかアルバム系サービス一通り使ってみた

花火大会

麻雀

会社の人の家でゲームパーティ

ベランダBBQ

タイ旅行

moumoonライブ

youtube

CLASの椅子導入

メルカリテックカンフ

沖縄家族旅行

めぞん一刻

iphoneXRへ

チームラボ

送別会

どんべえ

北海道旅行

hackday

福岡弾丸旅

仕事

冬はギフト券周りの改善。Rails移行をがっつり。pointシステムを構築するにはどうするか?など。トランザクションの大切さなど、クラス設計も結構学べた。

そこからわたしのウェディングのチームの中のエンジニアとして半年ほど。 チームは4人でデザイナーの人は入れ替わりがあったけど、半年間チームでPJをどう進めるか、何を作るかを議論できたのはよかった。 何よりもチームビルディングが大切でこれがしっかりできていればチームメンバのモチベーションが高く保ち続けることができることを肌でわかったと思う。 そしてそれを行動としてやるってなったときに圧倒的熱量でやるぞ!!と引っ張って、チームメンバと向き合わないといけない。

インターンのメンターをやった。

入社式があった。後輩ができた。

「IKUSEIonRails」タイトルで、RailsDMにて登壇 f:id:Saku-Saku:20181230232131j:plain

コーデdayとかやって楽しかった。 f:id:Saku-Saku:20181230232706j:plain

くふうカンパニー設立。 これは会社の動きとして大きかったんじゃないかなと思う。 中にいるともちろん変化は感じるけど、どうなっていくのかっていうのを中と外から考えられないといけないなぁと思う。変革の中にチャンスはあると思うので、手はしっかり挙げる。

メルカリテックカンフ参加 ちょいちょい勉強会には参加してたんじゃないでしょうか。

内定式があった。

来年こうしたい

自分の中でざっくりとあるのが、中途半端なことをしない、やりだしたら自分の決めたラインまではやることを徹底したい。 はじめてみたもののそのままになっちゃったことが多いからかな。 バッターボックスに立つのはめちゃ重要と認識しているので、やってみます!と手を挙げるのははこのまま継続するとして、それをどこまでやるのかっていうのをもう少し考えた方がいいかなぁと。 わかりやすくまではどこまでやるかっていうのを可視化するために、マイルストーンをめっちゃ小さくしてちょっとずつ積み上げたい。

実際これやりてェ!ドン!で出してもあんまりやらないなーとかできないことがわかってきた。 けどちまちました積み上げの効力を実感したことは今年ちょいちょいあったので、これをちゃんとやる。

仕事面だと自分が関わった施策で成果、結果を出したい。 これやりましたよっていうのを残したいですね。

Peproもちゃんと動かしていきたい。 まずは、今作ろうとしていたアイデアのものを一旦形にしてみるっていう部分をやるか、と。

あとちまちま続けているブログにももう少しコミットしたい。

自己レビュー力をUPしてレビュられる回数を少なくする 見直しをしようってところですねw

来年これやりたいリストはインプットとアウトプットをわけて、drop box paperにまとめようと思います!

Railsにおける例外処理の考え方とテストでは何をテストするべきか?講座

ども!桜庭パスタ郎(@apapway)です。

こちらの記事は、くふうカンパニー Advent Calendar 2018の21日目の記事となります。

くふうカンパニー Advent Calendar 2018 - Qiita

例外処理、みなさんどうするべきなのかちゃんと把握しているでしょうか?

正直言います。 ワタクシ、ちゃんと理解していませんでした!!!

この度、会社の先輩に教えていただくことがありましたので、そちらをまとめます!

実はこちらの記事がサラサラ読めて最高にわかりやすいので、こちらも必読です。

Railsアプリケーションにおけるエラー処理(例外設計)の考え方 - Qiita

例外処理ってなんだろう?

簡単に言うならば、エラーの処理ってところでしょうか。

イメージとしては、Railsを書いていて開発中にアクセスして赤い画面がでてますよね。あれ、エラー画面です。

例外が発生するとアプリケーションを止めてどこでエラーが生じたのかを表示、発生させます。

エラーがでたらアプリケーションが止まっちゃっている状態のような感じですね。

で、止まっちゃうと困る、みたいなケースもありえるわけです。 そんな時に、こういう例外だったらこう動作してほしいというケースに対応したりもする必要がでてきます。

今回はcsvファイルをアップロードするフォームオブジェクトを作っていたときの例でみていきましょう。

実際にこんなフォームオブジェクトのケースがありました

実際に指摘していただいたときのコードを紹介しましょう。

class UserForm
    include ActiveModel::Model

    attr_writer :csv_table
    attr_accessor :csv

    validates :csv, presence: true
    validate :ensure_csv_data, if: :check_csv_presence

    def save
      return unless valid?

      begin
        UserRegister.new(csv_file_path).save!
      rescue ActiveRecord::RecordInvalid
        errors.add(:invalid_error, "が含まれています")
        return false
      rescue ActiveRecord::RecordNotSaved
        errors.add(:save_error, "保存に失敗しました")
        return false
      rescue
        errors.add(:save_error, "に失敗しました")
        return false
      end
    end

  # 一部省略
end

こんな感じで書いていて「これは不要なじゃないか?」と指摘があった部分は、

    rescue
        errors.add(:save_error, "に失敗しました")
        return false

この部分ですね。

これを書いたときの自分の思想としては

「なにか例外が起こったらひとまず、例外をキャッチしてerrorsに追加。falseを返しておこう。」

といった具合でした。

これ!ダメです。色々とまずいです。反省です。順を追って説明していきます。

ちょっと待とう!例外のそもそもの考え方。

そもそもエラーにはどういうエラーがあるのかを認識しましょう。

エラーには、業務エラーとシステムエラーがあります。

業務エラーというものは、フォームへの入力に全角が入ってしまっている、メールアドレスが正しいフォーマットではない、といったものです。

システムエラーには、ネットワークが途中で切れてしまった、データベースが落ちてしまっているといったことがあります。

で、業務エラーというものはユーザが入力を間違えてしまったりしているので、ユーザに修正してもらうことで正常な入力をしてもらうことができます。

Rails書いている人は valid?して、エラー内容をフォームに表示させることを1度はやったことがあるはずです。

システムエラーは、ユーザではなくって開発者側で復旧させる必要があります。

ユーザにはどうしようもないですからね。

ということで、ここらへんを頭に入れた状態で先ほどのコードをみながら修正していきましょう。

さらには、何をテストするのといいのかを考えていきましょう。

不要な例外処理を消す

先ほどのコードを再度掲載しますね。

class UserForm
    include ActiveModel::Model

    attr_writer :csv_table
    attr_accessor :csv

    validates :csv, presence: true
    validate :ensure_csv_data, if: :check_csv_presence

    def save
      return unless valid?

      begin
        UserRegister.new(csv_file_path).save!
      rescue ActiveRecord::RecordInvalid
        errors.add(:invalid_error, "が含まれています")
        return false
      rescue ActiveRecord::RecordNotSaved
        errors.add(:save_error, "保存に失敗しました")
        return false
      rescue
        errors.add(:save_error, "に失敗しました")
        return false
      end
    end

  # 一部省略
end

ふむふむ。業務エラーとシステムエラーな部分に着目してみてみましょう。

Railsでは業務エラーは ActiveModel::Model や自分でvalidationを追加することでほぼカバーできます。

システムエラーはこのコードでいうとUserRegister.save!の中で起こりうるようにしています。 ここでデータベースに保存する処理がかいてあるため、業務的にvalidationを突破して要件をみたした内容を保存しようとするときにDBの問題でエラーがおきたとします。

これは基本的には ActiveRecordで起こりうることが想定できるため、ActiveRecord::RecordInvalidActiveRecord::RecordNotSavedのケースは動作を指定してあげたいのです。

ここでいうと、このUserFormclassのsaveメソッドの返り値をfalseにしてあげて、errorsにも追加してあげる、と。

じゃあその他の例外についてはどうするとよさそうか?

ネットワークのエラーなどはこのformで検知する必要はなく、Railsのアプリ側でエラーは吐いてくれるためここでrescueする必要はありません。

さらに言えば、その他の例外を全部補足しようとすると rescueだけではできません。

なぜなら、このrescueだけの記述で処理に対応するのはStandardErrorのサブクラスだけであるためです。

エラーにはこんなに種類があるのですね。

Ruby Exceptions

なるほど、このフォームでは想定し得るエラーは例外処理として捕捉するとして、その他のもっと広いエラーはいうなれば他の箇所でも起こりうるため、

より広い範囲をカバーするRails全体のエラーとしてしてあげればいいんだな、と。

ということで、このformのコードで捕捉するのは、ActiveRecord::RecordInvalidActiveRecord::RecordNotSavedだけでよさそうです。

じゃあテストするぞ

その他のエラーは捕捉しないとわかったところで、テストも修正していきます。

context "raise other exception" do
  before { allow(station_save).to receive(:save!).and_raise(NoMethodError) }

  it { is_expected.to be_falsey }
end

もともとActiveRecord::RecordInvalidActiveRecord::RecordNotSaved以外の例外が発生した時に falseを返すようにしているんだから以上のようなテストが必要だろうと思って追加していました。

が、こちらはもう必要ない、と。

他の例外が起こった時はエラーとなってもOKということです。このformでテストする内容ではないですね、するとしたらRailsのもっと広いスコープ部分でテストするのかな?

さて、ここでformのクラスのsaveメソッドで何をテストするべきかを整理してみましょう。

saveメソッドで起こりうる事象は全部で4つです。

  • valid?で invalidなパラメータがあってnilが返る
  • 正常に保存される
  • save!で例外が発生して falseが返る ActiveRecord::RecordInvalid
  • save!で例外が発生して falseが返る ActiveRecord::RecordNotSaved

こうやって書き出してみると何をテストすればいいか、シンプルですよね。

この4つのふるまいをテストすればいいんです。

こう考えると、他の例外が起こりうるケースをテストしなくてもいいのかな?と考えた時にどうすればいいかわかりやすいと思います。

テストコードは省略します。このコードでいうところのtipsがあるとすれば、mockをうまく使うことでテストはシンプルに作ることができると思います!

まとめ

例外ってなんだかざっくりしかわかっていないなーと思っていたところが先輩の教えてくれたことがきっかけで理解が深まりました。

なんだかよくわからないと思っている部分は自分でググることも大切ですが、理解している人に聞く、教えてもらうのも大切ですね。

例外もしっかり理解して、堅牢に作っていくことができそうです!!

【Hackday2018】17卒同期エンジニアで開発だ!

ども!くふうカンパニーアドベントカレンダー、15日目も担当の@KotaSakurawiです。

12月15日はYahoo!さんが主催するHackday2018の開催日です!

実はHacyday2017も参加していまして、2年連続の参加になります! さらに!2年連続メンバーも同じ構成で参加しておりまして、2017年新卒入社の同期メンバーです。

ということで、非常に大きなハッカソンに同期5人で参加したぞというレポートを見ていただければなと思います。

Hackday2018の会場へ行く!

会場は、秋葉原にあるUDXという会場で行います! 4Fのフロアをほぼ貸し切って総80チーム近くのメンバーで「ものづくり」を行います。

秋葉原は東京駅からも近く、遠方の方も参加しやすいですし電気街のイメージもあってハックな雰囲気がでていますよね。

この辺は電子部品などもすぐに買いに行けますし、ハードウェアを作る時にも非常に便利な立地です。

何を作ろうかな!?

今回、何を作ろうかなと考えたときに去年のとるだけYoutuberのプロダクトのことを考慮しました。

というのも、トレンドにのったものを作りたいと思ったのです。

そこで、今回は今年はやったもの2つを踏まえたプロダクトにするアイデアを思いつきました。

その2つとは、

  • 決済アプリ(電子マネー)
  • PokemonGO

です。

決済アプリで言えば、PayPayのキャンペーンがかなりバズっており、12月15日現在も興奮冷めやらぬ熱量がありました。(キャンペーン自体は終了になりましたが)

そこで電子マネーという流行は踏まえたいと強く思っていました。

2つめのPokemonGOは以前から流行っており、ここ最近さらにユーザが増えているなという肌感がありつつ自分も再度ハマってきた体験が大きいです。

東京で街を歩けば、PokemonGOをプレイしている人と多くすれ違います。

再び起動して遊んでみると、やっぱり面白いんですよね。

レアなポケモンを入手したらうれしいですし、友達とのトレードも楽しいです。

そんな背景もあり、この2つの要素ははずせないと思いました。

実際に作ったプロダクトは、HackDay2018の発表をお待ちください(追記もする予定です)

開発的な話をしたい!作っていくぞ!

今回は普段から業務で書いているRailsを使って開発することにしました。

みんなスムーズに書くことができますからね。

普段の業務では使わないrails newコマンドなども久々に叩きました。笑

環境を整える

いつもruby 2.4.4使ってたので、最新の使うぞーということで、2.5.3をみんなでインストールしました。

地味にインストールに時間がかかりました。wi-fiが途中で途切れかけるなんてことも。

rails newするタイミングで2.4.4で作成されてしまっていたりして修正したりも新鮮でした。

今回はhackdayの運営がslackを用意されていたため、そこで会話したりファイルを投げたりもできるので非常に楽でした。

githubの通知も入れたりと普段に近い開発環境を作れました。

リポジトリをorganizationにすると便利!

リポジトリは最初は自分のアカウントの配下に作成したのですが、herokuの設定をするときなど、他のメンバーが行おうとするとgithubでの設定が必要になるケースがありました。

そこで、organizationに作って、全員招待してadminの設定を行うことでスムーズに開発を進めることができました!

個人的にはあまりorganizationを使うことがないので、よかったです。

organizationを作ったあとは、リポジトリをtransferすることで移すことが可能です。

settingの部分から行うことができますね。

フォームで、そのリポジトリ名と、organization名を入力すれば、transfer完了です。

接続チェックやフォーム入力を忘れずに!

ハッカソン中には、最後の発表の準備としてチーム名やプロダクト名を投稿する必要があるので、ココは忘れずに!

基本的に例年22時くらいまでには決めて投稿しましょう。

そして、大事なのが接続チェックですね。

実際に発表で使うPCで接続の確認をします。

音声やスライドの表示などしっかりとチェックしておきましょう!

音声などを出す場合は、システムの環境設定で接続時にサウンドの出力先を切り替えたりしなければいけません。

また、動画がスライドの中で流れるか、拡張子は問題ないか、音量の大きさもざっくりチェックしておけるとよいと思います。

ハッカソンは楽しい!

やっぱり2日間で作り上げるハッカソンは面白いですね。

メンバーが徐々に集まってくる感じや、お昼ご飯をサッと食べに行ったり、実装のアイデアなど「こうしたらおもしそうじゃない?!」などなど。

どんどん機能が完成してすぐに触っていく感じも面白い!と感じるポイントですね。

また、自分んスキルも生かしてココならこうやったら面白くできそう!と思うものをドンドン追加もしていけるのもいいですね。

個人的には同期と毎年出場するイベントにしていきたい、なんて考えています。

社会人にとっては普段の土日まるまる使うのは少ししんどいですが、それ以上に「面白い」と思える要素がたくさんつまっています。

皆さんも是非、来年のhackdayに参加してみてはいかがでしょうか!?

Rails2年目のさく氏による, stimulus試した実践ガイド

どうも! くふうカンパニーアドベントカレンダー、7日目担当の@KotaSakurawiです。

くふうのアドカレはこちらから▶︎くふうカンパニー Advent Calendar 2018 - Qiita

今日の記事は! フロント寄りの内容になります。Stimulusについて触る機会がありましたので、こんな感じに書いていくよ、という説明をします!

続きを読む

知名度ゼロでも「この会社で働きたい」と思われる社長の採用ルール48 を読んだ感想

知名度ゼロでも「この会社で働きたい」と思われる社長の採用ルール48を読みまして、その感想などをまとめておきます。

知名度ゼロでも「この会社で働きたい」と思われる社長の採用ルール48

  • 感想
  • 大事なところ、面白いと思ったところ
  • まとめ
続きを読む