Try T.M Engineer Blog

多摩市で生息するエンジニアが「アウトプットする事は大事だ」と思って始めたブログ

34歳で技術力が無くて不安を感じていた人がWeb系エンジニアに転職した話

はじめに

この度、約11年程いた会社から新しい会社に転職しました。
34歳になってからのはじめての転職です。

前職は客先常駐で金融系のSE(システムエンジニア)をしていたのですが、以下の悩みがあり「Web系のサーバーサイドエンジニア」へと転職しました。同じような事で悩んでいる方々の参考になれば幸いです。

[転職前の悩み]
  • もうすぐ子供が産まれるけど、子育てをする余裕が無い。
  • 今の職場で働いていても技術力(プログラムを書く力)がつかない。
  • もし、今の会社が潰れた時に周りにアピールできる技術が無くて不安。
  • 技術について話せる人が周りにいない。
  • 自分の考えが上司に理解されず、職場移動をしてもらえない。

前職の内容と自身の思考について

客先常駐で金融系のSEをしていました。ネット上で良く話題に上がるSESですね。
SEとしてプログラムを書いていたのは入社してほんの2〜3年です。その後はマネジメントとして、ずっとリーダー業務をしていました。
マネジメントやリーダー業務と聞いて、イメージが沸かない人のために簡単に言うと「お客さんと話して、案件を貰って、開発作業をメンバー(パートナーさん)に振る」事をしていました。簡単そうに見える仕事ですが、これらを3〜4つ並列で行い、加えてお客さんからの急な依頼や問い合わせ等も発生するため、メンバーの進捗や工数(作業に掛かる時間やお金)を管理して、お客さんへの報告や課題の共有等を行う事が私の仕事でした。

「この仕事自体に不満はありませんでした。」と言えば、それは嘘になりますが、無数に降ってくるお客さんからの依頼や作業に対して、誰かが管理し、お客さんと話をしなくてはいけないので、仕事のやりがいは感じていました。

ただ、この仕事を続けていても他に潰しがきかなくなるのでは?という、ざっくりな不安というものは感じていました。
例えば「プログラムを書いていた経験が殆ど無いけど、それが無くても通用していたのは金融系でレガシーな技術しか使われなかったからではないのか?」「最近では金融系でもAWSやIoT等の新しい技術が使われはじめているけど、それについていけるのか?」「もし、今の会社が潰れた時に目に見える技術力が無いけど大丈夫なのか?」等です。

こういった不安から、もっと人の目に見える潰しのきく技術力を身につけよう。と考えていました。

転職を決めたきっかけ

転職をしようと思ったきっかけは、以下の3つです。

「もうすぐ子供が産まれるけど、子育てをする余裕が無かった」
前職は、通勤に01:40程掛かり、出社時間が08:40だったので07:00には家を出なくてはなりませんでした。 そうなると、朝は06:00前には起床する必要があり、帰りも遅い事が多いので、この生活を子供が産まれてからも続けるのは無理があるなと感じていました。

「職場移動ができない」
転職を考える前に職場移動の希望を会社に出しましたが「リーダーポストにいて、お客さんから信頼を得ている人を簡単に移動する事はできない」との事で、職場移動は何年も先になる(事実上不可能?)との事でした。

「会社、会社の上司との考え方が合わない」
会社自体の方向性もそうでしたが、会社の上司とも考え方が合いませんでした。私は「技術力を身に着けたい(プログラムを書きたい)」と上司に相談しましたが、「そんなものは会社は求めていない。プログラムを書くのはパートナーの仕事だ。」と一蹴されました。

一番大きかったのは、自分の考えと会社(上司)との考え方が一致していない事でした。
ここから私の転職活動が始まりました。

転職してどう変わったのか

転職活動を経て、無事Webエンジニアとして働く事になりました。
プログラムを書く技術が殆ど無いにも関わらず、採用(オファー)して頂いた今の会社には感謝しかありません。まだ、働いて2週間ですが、こんな感じに変わりました。

出社時間: 08:40 → 10:00
通勤時間: 01:40 → 01:00
仕事内容: リーダー職 → サーバーサイドエンジニア(プログラマー
自分の席: ない → ある

出社時間が遅くなったのと通勤時間が短くなったので、これなら子供が産まれても色々と余裕がありそうです。

仕事内容が変わった事が一番大きく、前職では1日の半分以上が打合せだったのですが、今ではゼロです。自席でずっとプログラムを書く生活に変わりました。

前職は客先常駐だったので自分の机というものが無かったのですが、今は受託開発の会社なので自分の机があります。これも大きく変わった事の1つです。

で、転職して良かったの?悪かったの? 今後はどうしたいの?

今はまだ働き始めて2週間なので、転職して良かったかどうかの判断は保留にしたいと思います。まずは1年を今の会社で働いて、それから結論を出したいと思います。

あと、今後は転職前から考えていた通り人の目に見える潰しのきく技術力(プログラムを書く力)を身につける事を目標にがんばりたいと思います。まだ転職したてなので、偉そうな事は言えませんが、30代で同じ様な事で悩んでいる方々の参考になれば良いかと思います。

[余談]その後の前職について

私が「技術力を身に着けたい(プログラムを書きたい)」と言った事に対して「そんなものは会社は求めていない。プログラムを書くのはパートナーの仕事だ。」と上司に言われた前職ですが、今では社員に技術力(プログラムを書く力)を身に付けさせようと色々と体制変更を行っている様です。
というのも、私が感じていた不安の通り?なのか、会社自体に技術力が無くて、今後の仕事が取れない(かもしれない)事を懸念しての体制変更なんだとか・・・
可能であれば、もっと早くに手を打って欲しかったなぁと思うばかりです。

Amazon echo dotのリマインダー機能で、薬の飲み忘れが極端に減った話

Amazon Echo Dotを購入して、約4ヶ月が立ったので、使用感と便利なリマインダー機能について書いていきたいと思います。

Amazon Echo Dotとは?

Amazonが販売しているスマートホーム。人の声に反応して、様々な情報を返してくれる便利なガジェットです。最近では、液晶画面付きのものも販売されている様ですね。

Amazon Echo Dot(液晶画面なし)
Echo Dot (エコードット) - スマートスピーカー with Alexa、ブラック

Amazon Echo Spot(液晶画面付き)
Echo Spot (エコースポット) - スマートスピーカー with Alexa、ホワイト

スマートホームを購入理由は?

約5ヶ月くらい前、のぼりーさんのクラウドインフラPodcastの『Event-01 Alexa Day 2018 出張インタビュー(神戸で行われたAmazon Echoを使ったTech Conferenceの話』を聞いて、スマートホームに興味を持ち、「面白そうだなぁ使ってみたいなぁ」と思ったのが購入のきっかけです。なので、ちょっとした玩具感覚での購入だった事もあり、GoogleHomeよりも安価なAmazon Echo Dotを購入しました。

意外と便利に感じたリマインダー機能

スマートホームは声に出すだけで、音楽をかけてくれたり、タイマーのセットや天気や交通情報を教えてくれるのは、とても未来感があって新鮮に感じました。中でも重宝しているのはリマインダー機能1です。
僕は毎朝、薬を飲んでいる(飲まなくてはならない)のですが、これがなかなか継続できなくて困っていました。朝御飯食べた後に薬を飲む。という事が頭の中でわかっていても、朝は出社の準備等に夢中で余裕が無く、つい忘れてしまう。というのが良くありました。(意外と同じ様な方々は多いのではないでしょうか?)「毎朝、誰かが薬を飲む事を教えてくれないかなぁ」と調子の良い事を考えていたら、Amazon Echoにデフォルトでリマインダー機能が付いている事に気づき、さっそく登録して使ってみました。

すると、なんという事でしょう。
毎朝、僕が朝食を食べている時間帯に、Amazon Echoが、薬を飲む時間だと教えてくれるじゃありませんか!!

以降、タイトルの通り薬の飲み忘れが極端に減り、最初は玩具感覚で購入したスマートホームが意外にも生活改善の役に立ったというお話でした。

あと、リマインダー機能を使っていて面白い事が起きたのでこちらも書いておきます。
最初リマインダー機能に「○○さん、薬を飲む時間です。」と登録していたんですが、Amazon Echoは「○○さん薬 (やく)を飲む時間です。」と言ってきて、ビックリしたので前に「お」を付けて「お薬を飲む時間です。」に変更しました。いや、うちの奥さん大爆笑してましたけどね……(第三者が聞いてたら誤解されそうです(汗))


  1. Amazon echoデフォルトの機能で、日付と時間とリマインドして欲しい内容を登録すると、登録した時間にリマインドした内容を声に出して読み上げてくれる機能です。

【Ruby on Railsチュートリアル(第4版)】第9章 発展的なログイン機構(演習と解答)

はじめに

このブログ記事は、私(Kodak)自身のRailsの勉強記録として書いています。
Ruby on Railsチュートリアル』の演習と解答をもくもくと書いているだけの記事なので、興味の無い方は軽くスルーしてあげてください。他にも、まだ『Railsチュートリアル』の演習に挑戦していない方、これから『Railsチュートリアル』をやるぞ!という方は(演習の解答の)ネタバレになりますので、スルーしてください。

Ruby on Rails チュートリアルとは?

Ruby業界でRailsを使い始めるなら、まず最初に初めるRails入門サイトです。
電子書籍版は有料ですが、Webサイトにあるオンライン版は無料なので、誰でも読む(Railsにチャレンジする)事ができます。
railstutorial.jp
全部で14章あり、かなりのボリュームですが、これを読む事でRailsの基礎を学ぶ事ができ、ちょっとしたWebアプリケーションを作れるレベルにはなれる?とのこと。
各章毎に演習問題が複数あり、これを解いていく事でRailsへの理解を深めていく事ができる様になっています。

環境について

Ruby 2.5.0-dev
Rails 5.1.4
・バージョン管理ツール:GitHub(https://github.com/Kodak4400)

演習と解答

9.1.1 記憶トークンと暗号化<演習>
1. コンソールを開き、データベースにある最初のユーザーを変数userに代入してください。その後、そのuserオブジェクトからrememberメソッドがうまく動くかどうか確認してみましょう。また、remember_tokenとremember_digestの違いも確認してみてください。
【解答】以下の通り。

$ rails console --sandbox
Loading development environment in sandbox (Rails 5.1.4)
Any modifications you make will be rolled back on exit
irb(main):001:0> user = User.first
  User Load (0.4ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> #<User id: 1, name: "Rails Tutorial", email: "example@railstutorial.org", created_at: "2018-08-12 15:23:47", updated_at: "2018-08-12 15:23:47", password_digest: "$2a$10$j8YTAFtYA/b8uo0q0gqNX.9Zox3VCDNwhYkjMd6ET87...", remember_digest: nil>
irb(main):002:0> user
=> #<User id: 1, name: "Rails Tutorial", email: "example@railstutorial.org", created_at: "2018-08-12 15:23:47", updated_at: "2018-08-12 15:23:47", password_digest: "$2a$10$j8YTAFtYA/b8uo0q0gqNX.9Zox3VCDNwhYkjMd6ET87...", remember_digest: nil>
irb(main):003:0> user.remember
   (0.1ms)  SAVEPOINT active_record_1
  SQL (0.3ms)  UPDATE "users" SET "updated_at" = ?, "remember_digest" = ? WHERE "users"."id" = ?  [["updated_at", "2018-08-28 12:14:56.339679"], ["remember_digest", "$2a$10$JXbVWHZy9Y649zF9V5UgDOwueqLWMDsiPdoEUw2SLR3kN5qr/4aHC"], ["id", 1]]
   (0.1ms)  RELEASE SAVEPOINT active_record_1
=> true
irb(main):004:0> user.remember_token
=> "nCgSjbDAyJkTft85xVTCCA"
irb(main):005:0> user.remember_digest
=> "$2a$10$JXbVWHZy9Y649zF9V5UgDOwueqLWMDsiPdoEUw2SLR3kN5qr/4aHC"
irb(main):006:0>

2. リスト 9.3では、明示的にUserクラスを呼び出すことで、新しいトークンやダイジェスト用のクラスメソッドを定義しました。実際、User.new_tokenやUser.digestを使って呼び出せるようになったので、おそらく最も明確なクラスメソッドの定義方法であると言えるでしょう。しかし実は、より「Ruby的に正しい」クラスメソッドの定義方法が2通りあります。1つはややわかりにくく、もう1つは非常に混乱するでしょう。テストスイートを実行して、リスト 9.4 (ややわかりにくい) や、リスト 9.5 (非常に混乱する) の実装でも、正しく動くことを確認してみてください。ヒント: selfは、通常の文脈ではUser「モデル」、つまりユーザーオブジェクトのインスタンスを指しますが、リスト 9.4やリスト 9.5の文脈では、selfはUser「クラス」を指すことにご注意ください。わかりにくさの原因の一部はこの点にあります。
実機操作のため割愛。

9.1.2 ログイン状態の保持<演習>
1. ブラウザのcookieを調べ、ログイン後のブラウザではremember_tokenと暗号化されたuser_idがあることを確認してみましょう。
【解答】以下の通り。
f:id:special-moucom:20180830092424p:plain

2. コンソールを開き、リスト 9.6のauthenticated?メソッドがうまく動くかどうか確かめてみましょう。
【解答】以下の通り。

$ rails console --sandbox
Loading development environment in sandbox (Rails 5.1.4)
Any modifications you make will be rolled back on exit
irb(main):001:0> user = User.first
  User Load (0.1ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> #<User id: 1, name: "Rails Tutorial", email: "example@railstutorial.org", created_at: "2018-08-12 15:23:47", updated_at: "2018-08-28 14:19:43", password_digest: "$2a$10$j8YTAFtYA/b8uo0q0gqNX.9Zox3VCDNwhYkjMd6ET87...", remember_digest: "$2a$10$ngv5/yMYwIknzAmT.xNE/eEcplZiu2PVr7HscyaiAau...">
irb(main):002:0> user
=> #<User id: 1, name: "Rails Tutorial", email: "example@railstutorial.org", created_at: "2018-08-12 15:23:47", updated_at: "2018-08-28 14:19:43", password_digest: "$2a$10$j8YTAFtYA/b8uo0q0gqNX.9Zox3VCDNwhYkjMd6ET87...", remember_digest: "$2a$10$ngv5/yMYwIknzAmT.xNE/eEcplZiu2PVr7HscyaiAau...">
irb(main):003:0> user.remember
   (0.1ms)  SAVEPOINT active_record_1
  SQL (0.4ms)  UPDATE "users" SET "updated_at" = ?, "remember_digest" = ? WHERE "users"."id" = ?  [["updated_at", "2018-08-28 14:25:05.418184"], ["remember_digest", "$2a$10$g6KH9a8pP4rNF6n.aIFZ..HM/ShRzGLe0Fb.pkoUxtKn6u0m5isZ6"], ["id", 1]]
   (0.1ms)  RELEASE SAVEPOINT active_record_1
=> true
irb(main):004:0> user.remember_token
=> "8SqCVjnPAg7x8tGVE0UwHQ"
irb(main):005:0> user.authenticated?(user.remember_token)
=> true
irb(main):006:0>

9.1.3 ユーザーを忘れる<演習>
1. ログアウトした後に、ブラウザの対応するcookiesが削除されていることを確認してみましょう。
実機操作のため割愛。

9.1.4 2つの目立たないバグ<演習>
1. リスト 9.16で修正した行をコメントアウトし、2つのログイン済みのタブによるバグを実際に確かめてみましょう。まず片方のタブでログアウトし、その後、もう1つのタブで再度ログアウトを試してみてください。
【解答】実機操作のため割愛。

2. リスト 9.19で修正した行をコメントアウトし、2つのログイン済みのブラウザによるバグを実際に確かめてみましょう。まず片方のブラウザでログアウトし、もう一方のブラウザを再起動してサンプルアプリケーションにアクセスしてみてください。
【解答】実機操作のため割愛。

3. 上のコードでコメントアウトした部分を元に戻し、テストスイートが red から greenになることを確認しましょう。
【解答】以下の通り。

### app/models/user.rb
class User < ApplicationRecord

  # 渡されたトークンがダイジェストと一致したらtrueを返す
  def authenticated?(remember_token)
    return false if remember_digest.nil?
    BCrypt::Password.new(remember_digest).is_password?(remember_token)
  end

  # ユーザーのログイン情報を破棄する
  def forget
    update_attribute(:remember_digest, nil)
  end
end
### app/controllers/sessions_controller.rb 
class SessionsController < ApplicationController

  def destroy
    log_out if logged_in?
    redirect_to root_url
  end
end
$ rails test
Finished in 0.754003s, 33.1564 runs/s, 91.5116 assertions/s.
25 runs, 69 assertions, 0 failures, 0 errors, 0 skips
$

9.2 [Remember me]チェックボックス<演習>
1. ブラウザでcookies情報を調べ、[remember me] をチェックしたときに意図した結果になっているかどうかを確認してみましょう。
実機操作のため割愛。

2. コンソールを開き、三項演算子を使った実例を考えてみてください (コラム 9.2)。
【解答】以下の通り。

$ rails console --sandbox
Loading development environment in sandbox (Rails 5.1.4)
Any modifications you make will be rolled back on exit
irb(main):001:0> def your_name?(name)
irb(main):002:1>  name == 'Kodak' ? "yes" : "no"
irb(main):003:1> end
=> :your_name?
irb(main):004:0> your_name?("Kodak")
=> "yes"
irb(main):005:0> your_name?("Magikarp")
=> "no"
irb(main):006:0>

9.3.1 [Remember me]チェックボックスをテストする<演習>
1. リスト 9.25の統合テストでは、仮想のremember_token属性にアクセスできないと説明しましたが、実は、assignsという特殊なテストメソッドを使うとアクセスできるようになります。コントローラで定義したインスタンス変数にテストの内部からアクセスするには、テスト内部でassignsメソッドを使います。このメソッドにはインスタンス変数に対応するシンボルを渡します。例えばcreateアクションで@userというインスタンス変数が定義されていれば、テスト内部ではassigns(:user)と書くことでインスタンス変数にアクセスできます。本チュートリアルのアプリケーションの場合、Sessionsコントローラのcreateアクションでは、userを (インスタンス変数ではない) 通常のローカル変数として定義しましたが、これをインスタンス変数に変えてしまえば、cookiesにユーザーの記憶トークンが正しく含まれているかどうかをテストできるようになります。このアイデアに従ってリスト 9.27とリスト 9.28の不足分を埋め (ヒントとして?やFILL_INを目印に置いてあります)、[remember me] チェックボックスのテストを改良してみてください。
【解答】以下の通り。

### app/controllers/sessions_controller.rb
class SessionsController < ApplicationController

  def create
    @user = User.find_by(email:params[:session][:email].downcase)
    if @user && @user.authenticate(params[:session][:password])
      # ユーザーログイン後にユーザー情報ページにリダイレクトする
      log_in @user
      params[:session][:remember_me] == '1' ? remember(@user) : forget(@user)
      redirect_to @user
    else
      # エラーメッセージを作成する
      flash.now[:danger] = 'Invalid email/password combination' #本当は正しくない
      render 'new'
    end
  end

end
class UsersLoginTest < ActionDispatch::IntegrationTest

  test "login with remembering" do
    log_in_as(@user, remember_me:'1')
    assert_equal cookies['remember_token'], assigns(:user).remember_token
  end

end
$ rails test
Finished in 0.706577s, 38.2124 runs/s, 101.8997 assertions/s.

27 runs, 72 assertions, 0 failures, 0 errors, 0 skips

9.3.2 [Remember me]をテストする<演習> 1. リスト 9.33にあるauthenticated?の式を削除すると、リスト 9.31の2つ目のテストで失敗することを確かめてみましょう (このテストが正しい対象をテストしていることを確認してみましょう)。 【解答】以下の通り。

### app/helpers/sessions_helper.rb
module SessionsHelper

  def current_user
    if(user_id = session[:user_id])
      @current_user ||= User.find_by(id:user_id)
    elsif (user_id = cookies.signed[:user_id])
      user = User.find_by(id:user_id)
  #   if user && user.authenticated?(cookies[:remember_token])
      if user
        log_in user
        @current_user = user
      end
    end
  end
Failure:
SessionsHelperTest#test_current_user_returns_nil_when_remember_digest_is_wrong [rails-tutorial/sample_app/test/helpers/sessions_helper_test.rb:17]:
Expected #<User id: 762146111, name: "Michael Example", email: "michael@example.com", created_at: "2018-08-29 13:39:31", updated_at: "2018-08-29 13:39:31", password_digest: "$2a$04$m6OP7WuMes8ezEStQDXfJenCq3N8XncZGmN4sgJ8Php...", remember_digest: "$2a$04$ZqqQuHUiHVdszcZNt2ZTDekJjOVrZgtmAWNJ5JjTQl0..."> to be nil.

「HTML5/CSS3モダンコーディング」はちょっと難しいけど、モチベーションが保てて良い本だった件

はじめに

最近、RailsチュートリアルJavaサーブレット等、サーバーサイド側の勉強が続いていたので、ここいらでフロントエンド側も勉強したいと思い、この本を手にしました。
手を動かしてコードを書いて学習するスタイルで、とりあえず一周終えたので感想を書いていきたいと思います。

「HTML/CSS3モダンコーディング」の感想

正直な感想を言うと、僕がこの本を読むのは少し早かったかな・・・と感じるところがありました。
しかし、本書がスタンダード・グリッド・シングルページレイアウトにポイントを絞って書かれていた事もあり、最低限これだけ知ってれば、こんなWebページを作れるよ。という大枠を知る事ができたので、結果的に購入して良かったです。
また、本書の解説で使用しているWebページは以下の通りデザインも素敵なので、多少難しくてもモチベーションが保てたところがとても良かったです。
f:id:special-moucom:20180827220318p:plain f:id:special-moucom:20180827220345p:plain f:id:special-moucom:20180827220305p:plain

PART0:イントロダクションがCSS初心者にとって大変勉強になった

CSSにあまり触れてこなかった僕自身としては、このPART0:イントロダクションは凄くためになりました。 特に「要素名にスタイルを指定しない」「classとidの違い」「リセットHTML」等の初心者が気をつけるべきポイントや気になる部分を丁寧に解説されていて、僕自身初めて知る事ばかりだったので大変勉強になりました。

PART1:スタンダードレイアウトの学習がとにかく大変だった

CSSにあまり触れてこなかった人は、PART1:スタンダードレイアウトを読むのが一番大変なのではないでしょうか。僕は凄く大変に感じました。
いきなりclearで回り込みを解除する。とか言われても全然頭に入ってこなかったので、このあたりが「あ、この本を読むのは少し早かったかな」と感じた部分だったかもしれません。
しかし、「そもそも回り込みとは何なのか。」Googleで調べて実際にコーディングする事を繰り返し、理解していきました。
一応、誤解を与えないように言うと、本書ではclearやmargin等の初心者がつまづきやすい箇所は、ちゃんと別枠を設けて説明が記載されています。なので、こちらを読めばGoogleで調べなくても理解できる人は理解できるはずです。ただ、僕は本書に書かれている内容だけではいまいち理解できない部分があったので、そこをGoogleで調べて理解していきました。

PART1:スタンダードレイアウトさえ理解できれば、PART2と3はそこまで難しくない

上記の通り、一番の難所はPART1:スタンダードレイアウトだと感じました。 PART1を読み終えた後のPART2と3はするすると読めたので、そこまで難しいと感じませんでした。 これは本書がWebページのレイアウト作成に重点を置いているからで、本書で使用されているCSSの種類が少ないからなのだと思います。
それでも、これだけ素敵なデザインのWebページを作ることができるので、凄いなと感じました。

本書を読み終えれば素敵なデザインのWebページが作れる様になるのか?

ならないです。(きっぱり!)
あくまで本書を読めば、HTMLとCSSの書き方やWebページのレイアウトの作り方が理解できるまでです。 素敵なデザインのWebページが作れる様になるには、やはりそれなりの経験(Webページを作る数)が必要なのだと感じました。
しかし、HTMLやCSSの書き方を学べた事で、この先やろうと考えていたjQueryの本はするすると読めそうです。 というわけで、次回はjQueryの本を読んでいきたいと思います。

【Ruby on Railsチュートリアル(第4版)】第8章 基本的なログイン機構(演習と解答)

はじめに

このブログ記事は、私(Kodak)自身のRailsの勉強記録として書いています。
Ruby on Railsチュートリアル』の演習と解答をもくもくと書いているだけの記事なので、興味の無い方は軽くスルーしてあげてください。他にも、まだ『Railsチュートリアル』の演習に挑戦していない方、これから『Railsチュートリアル』をやるぞ!という方は(演習の解答の)ネタバレになりますので、スルーしてください。

Ruby on Rails チュートリアルとは?

Ruby業界でRailsを使い始めるなら、まず最初に初めるRails入門サイトです。
電子書籍版は有料ですが、Webサイトにあるオンライン版は無料なので、誰でも読む(Railsにチャレンジする)事ができます。
railstutorial.jp
全部で14章あり、かなりのボリュームですが、これを読む事でRailsの基礎を学ぶ事ができ、ちょっとしたWebアプリケーションを作れるレベルにはなれる?とのこと。
各章毎に演習問題が複数あり、これを解いていく事でRailsへの理解を深めていく事ができる様になっています。

環境について

Ruby 2.5.0-dev
Rails 5.1.4
・バージョン管理ツール:GitHub(https://github.com/Kodak4400)

演習と解答

8.1.1 Sessionsコントローラ<演習>
1. GET login_pathとPOST login_pathとの違いを説明できますか? 少し考えてみましょう。
【解答】GET login_pathは、データを取得したい時に使用する。 POST login_pathはデータを送信したい時に使用する。

2. ターミナルのパイプ機能を使ってrails routesの実行結果とgrepコマンドを繋ぐことで、Usersリソースに関するルーティングだけを表示させることができます。同様にして、Sessionsリソースに関する結果だけを表示させてみましょう。現在、いくつのSessionsリソースがあるでしょうか? ヒント: パイプやgrepの使い方が分からない場合は Learn Enough Command Line to Be Dangerousの Section on Grep (英語) を参考にしてみてください。
【解答】以下の通り。

$ rails routes | grep sessions
sessions_new GET    /sessions/new(.:format)   sessions#new
       login GET    /login(.:format)          sessions#new
             POST   /login(.:format)          sessions#create
      logout DELETE /logout(.:format)         sessions#destroy

8.1.2 ログインフォーム<演習>
1. リスト 8.4で定義したフォームで送信すると、Sessionsコントローラのcreateアクションに到達します。Railsはこれをどうやって実現しているでしょうか? 考えてみてください。ヒント:表 8.1とリスト 8.5の1行目に注目してください。
【解答】"Sign up now!"のSubmitボタンの遷移先がsignup_pathになっているため。signup_pathは、Post users#createのコントローラアクションと紐付いている。

8.1.3 ユーザーの検索と認証<演習>
1. Railsコンソールを使って、表 8.2のそれぞれの式が合っているか確かめてみましょう. まずはuser = nilの場合を、次にuser = User.firstとした場合を確かめてみてください。ヒント: 必ず論理値オブジェクトとなるように、4.2.3で紹介した!!のテクニックを使ってみましょう。例: !!(user && user.authenticate(’foobar’))
【解答】以下の通り。

$ rails console --sandbox
Loading development environment in sandbox (Rails 5.1.4)
Any modifications you make will be rolled back on exit
# 存在しない(何でもよい)の確認
irb(main):001:0> user = nil
=> nil
irb(main):002:0> !!(user && user.authenticate('foobar'))
=> false
# 有効なユーザー(誤ったパスワード)の確認
irb(main):003:0> user = User.first
  User Load (0.4ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> #<User id: 1, name: "Rails Tutorial", email: "example@railstutorial.org", created_at: "2018-08-12 15:23:47", updated_at: "2018-08-12 15:23:47", password_digest: "$2a$10$j8YTAFtYA/b8uo0q0gqNX.9Zox3VCDNwhYkjMd6ET87...">
irb(main):004:0> !!(user && user.authenticate('aaaaa'))
=> false
# 有効なユーザー(正しいパスワード)の確認
irb(main):005:0> !!(user && user.authenticate('foobar'))
=> true
irb(main):006:0>

8.1.4 フラッシュメッセージを表示する<演習>
1. 8.1.4の処理の流れが正しく動いているかどうか、ブラウザで確認してみてください。特に、flashがうまく機能しているかどうか、フラッシュメッセージの表示後に違うページに移動することを忘れないでください。
【解答】実機操作のため割愛。

8.2.1 log_inメソッド<演習>
1. 有効なユーザーで実際にログインし、ブラウザからcookiesの情報を調べてみてください。このとき、sessionの値はどうなっているでしょうか? ヒント: ブラウザでcookiesを調べる方法が分からない? 今こそググってみるときです! (コラム 1.1)
【解答】以下の通り。
f:id:special-moucom:20180819161644p:plain

2. 先ほどの演習課題と同様に、Expiresの値について調べてみてください。
【解答】上記画像参照。ブラウザセッション終了時

8.2.2 現在のユーザー<演習>
1. Railsコンソールを使って、User.find_by(id: ...)で対応するユーザーが検索に引っかからなかったとき、nilを返すことを確認してみましょう。
【解答】以下の通り。

$ rails console --sandbox
Loading development environment in sandbox (Rails 5.1.4)
Any modifications you make will be rolled back on exit
## 検索に引っかかる場合
irb(main):001:0> user = User.find_by(email: "example@railstutorial.org")
  User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."email" = ? LIMIT ?  [["email", "example@railstutorial.org"], ["LIMIT", 1]]
=> #<User id: 1, name: "Rails Tutorial", email: "example@railstutorial.org", created_at: "2018-08-12 15:23:47", updated_at: "2018-08-12 15:23:47", password_digest: "$2a$10$j8YTAFtYA/b8uo0q0gqNX.9Zox3VCDNwhYkjMd6ET87...">
## 検索に引っかからない場合
irb(main):002:0> user = User.find_by(email: "test@test")
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."email" = ? LIMIT ?  [["email", "test@test"], ["LIMIT", 1]]
=> nil

2. 先ほどと同様に、今度は:user_idキーを持つsessionハッシュを作成してみましょう。リスト 8.17に記したステップに従って、||=演算子がうまく動くことも確認してみましょう。
【解答】以下の通り。

irb(main):005:0> session = {}
=> {}
irb(main):006:0> session[:user_id] = nil
=> nil
irb(main):007:0> @current_user ||= User.find_by(id: session[:user_id])
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" IS NULL LIMIT ?  [["LIMIT", 1]]
=> nil
irb(main):008:0> session[:user_id]= User.first.id
  User Load (0.1ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> 1
irb(main):009:0> @current_user ||= User.find_by(id: session[:user_id])
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
=> #<User id: 1, name: "Rails Tutorial", email: "example@railstutorial.org", created_at: "2018-08-12 15:23:47", updated_at: "2018-08-12 15:23:47", password_digest: "$2a$10$j8YTAFtYA/b8uo0q0gqNX.9Zox3VCDNwhYkjMd6ET87...">
irb(main):010:0> @current_user ||= User.find_by(id: session[:user_id])
=> #<User id: 1, name: "Rails Tutorial", email: "example@railstutorial.org", created_at: "2018-08-12 15:23:47", updated_at: "2018-08-12 15:23:47", password_digest: "$2a$10$j8YTAFtYA/b8uo0q0gqNX.9Zox3VCDNwhYkjMd6ET87...">
irb(main):011:0>

8.2.3 レイアウトリンクを変更する<演習>
1. ブラウザのcookieインスペクタ機能を使って (8.2.1.1)、セッション用のcookieを削除してみてください。ヘッダー部分にあるリンクは非ログイン状態のものになっているでしょうか? 確認してみましょう。
【解答】実機操作のため割愛。

2. もう一度ログインしてみて、ヘッダーのレイアウトが変わったことを確認してみましょう。その後、ブラウザを再起動させ、再び非ログイン状態に戻ったことも確認してみてください。注意: もしブラウザの [閉じたときの状態に戻す] 機能をオンにしていると、セッション情報も復元される可能性があります。もしその機能をオンにしている場合、忘れずにオフにしておきましょう (コラム 1.1)。
【解答】実機操作のため割愛。

8.2.4 レイアウトの変更をテストする<演習>
1. 試しにSessionヘルパーのlogged_in?メソッドから!を削除してみて、リスト 8.23が redになることを確認してみましょう。
【解答】以下の通り。

### app/helpers/sessions_helper.rb
module SessionsHelper

  # ユーザーがログインしていればtrue、その他ならfalseを返す
  def logged_in?
    current_user.nil?
  end
end
$ rails test test/integration/users_login_test.rb
Failure:
Expected exactly 0 elements matching "a[href="/login"]", found 1..
Expected: 0
  Actual: 1

2. 先ほど削除した部分 (!) を元に戻して、テストが greenに戻ることを確認してみましょう。
【解答】以下の通り。

### app/helpers/sessions_helper.rb 
module SessionsHelper

  # ユーザーがログインしていればtrue、その他ならfalseを返す
  def logged_in?
    !current_user.nil?
  end
end
$ rails test test/integration/users_login_test.rb
Finished in 0.537099s, 3.7237 runs/s, 18.6185 assertions/s.
2 runs, 10 assertions, 0 failures, 0 errors, 0 skips
$

8.2.5 ユーザー登録時にログイン<演習>
1. リスト 8.25のlog_inの行をコメントアウトすると、テストスイートは red になるでしょうか? それとも green になるでしょうか? 確認してみましょう。
【解答】以下の通り。ユーザー作成後にログインしていない状態となるため、テストではREDになる。

### app/controllers/users_controller.rb
class UsersController < ApplicationController

  def create
    @user = User.new(user_params)
    if @user.save
      # log_in @user
      flash[:success] = "Welcome to the Sample App!"
      redirect_to @user
    else
      render 'new'
    end
  end

end
$ rails test
Failure:
Expected false to be truthy.

2. 現在使っているテキストエディタの機能を使って、リスト 8.25をまとめてコメントアウトできないか調べてみましょう。また、コメントアウトの前後でテストスイートを実行し、コメントアウトすると red に、コメントアウトを元に戻すと green になることを確認してみましょう。ヒント: コメントアウト後にファイルを保存することを忘れないようにしましょう。また、テキストエディタコメントアウト機能については Test Editor Tutorial の Commenting Out (英語) などを参照してみてください。
【解答】実機操作のため割愛。(参考)私が使用してるテキストエディタVimですが、コメントアウトは、Ctl-v → G → I → "#"を入力 → esc で可能。

8.3.4 失敗時のテスト<演習>
1. ブラウザから [Log out] リンクをクリックし、どんな変化が起こるか確認してみましょう。また、リスト 8.31で定義した3つのステップを実行してみて、うまく動いているかどうか確認してみましょう。
【解答】実機操作のため割愛。

2. cookiesの内容を調べてみて、ログアウト後にはsessionが正常に削除されていることを確認してみましょう。
【解答】実機操作のため割愛。