パーフェクトRuby on Rails輪読会を完走しました

はじめに

フィヨルドブートキャンプというプログラミングスクール内で開催されていた「パーフェクトRuby on Rails」の輪読会を完走しました。 この記事はその内容をまとめたものです。

  パーフェクト Ruby on Rails 【増補改訂版】 | すがわら まさのり, 前島 真一, 橋立 友宏, 五十嵐 邦明, 後藤 優一 | コンピュータ・IT | Kindleストア | Amazon

いつ始まった?

フィヨルドブートキャンプ受講生の「『パーフェクトRuby on Rails』を読みたいけど、今の自分にはハードルが高いかも...」という声に対して、五十嵐さん*1が「フィヨルドブートキャンプ内で輪読会をやれば良いのでは?」と提案されたことがきっかけで始まりました。 初回が2020年8月9日に開催されているので、約1年かけて読み切ったことになります。

輪読会の概要

毎週日曜の8:30〜10:30にZoomで開催していました。

時間を決めて全員で黙読し、気づいたことやわからなかったことをHackMDに書いて、その内容について議論していくスタイルでした。

6章から9章は例外で、イベント告知アプリケーションとGithub Actionsに関する内容は手を動かしたかったのでモブプログラミングを実施していました。

こちらが実際に使われていたHackMDです。52回もやっていたと思うと感慨深いです。 hackmd.io

章ごとにかかった時間

だいたいこんな感じのペースで読んでいました。

期間
1章 1ヶ月弱
2章 1ヶ月
3章 1ヶ月弱
4章 2週間
5章 2週間
6章 2ヶ月
7章 1ヶ月
8章 2ヶ月
9章 2ヶ月弱
10章 1週間
11章 1週間
12章 2週間
13章 2週間

モブプロをしていた6章から9章だけで約7ヶ月かかっています。 もしモブプロしていなかったらおそらく1年はかからなかったのでは、と思います。 時間はかなりかかりましたが、後述するとおり一人で書籍を読んでいるだけではできない経験が積めました。

モブプロで使用していたリポジトリはこちら↓ github.com

良かったこと

わからないことがあってもその場で著者に質問できた

五十嵐さんが毎回参加して質問に答えてくださったのはとにかく贅沢な経験でした。 モブプロのドライバーもやってくださり、あっという間にプルリクエストが出されている様を見て衝撃を受けました。

モブプロでプログラマーの作法的な部分も学べた

モブプロでは、きりのいいところまできたらドライバーがプルリクエストを作成して、他の誰かがレビューしてマージするという手順を踏んでいました。 書籍の内容だけではなく、プルリクエストのdescriptionの書き方、コミットの分け方、コミットメッセージの書き方、Gitの使い方などの作法を学びました。

同じエディタを使っている人の作業を見ることができた

モブプロをやり始めた当初はRubyMineを使いたての頃だったのですが、RubyMineを使っている他の参加者から便利な機能を教えてもらってすごく助かりました。

f:id:hogucc:20210829170429p:plain
五十嵐さんにプルリクエストの書き方を教えてもらった回の参加者の感想その1

f:id:hogucc:20210829170050p:plain
感想その2。この回はGitやエディタの使い方の話でも盛り上がっていた様子

会の運営も経験できた

最初はただの参加者だったのですが、毎回参加していて気づいたら運営メンバーの一人になっていました。 主に以下の仕事をしていました。

  • 輪読会中
    • 司会(HackMDに書かれている内容を拾って議論を促したり、休憩時間をとるタイミングを見極めたり)
    • タイマー係(黙読するときや休憩時間のタイマーをセットする)
  • 輪読会後
    • 各章を何分で読むかの目安時間を決める
    • 章によってどういうスタイルで進めるのが最適かを議論

運営の立場も経験して気づいたのは、輪読会を1年間継続して開催するのはすごく大変ということです。 1年も経てば参加者それぞれの生活に大小さまざまな変化があります。 それでも継続して参加してくれた方がいたり、運営を続けてきたメンバーがいたからこそ完走できたと思っています。 ちなみに、開催してから1年の間に運営に関わったフィヨルドブートキャンプ受講生5人は、全員スクールを卒業してエンジニアになったという裏話があります。

おわりに

運営は大変でしたが、その分学んだこともたくさんあり、最初から最後まで参加して良かったと改めて思います。 参加してくださった皆様、ありがとうございました!

五十嵐さん、1年間大変お世話になりました! いつも丁寧に質問に答えてくださって、五十嵐さんから学んだことがたくさんありました。 ありがとうございました!

自分がレベルアップしたときに読んだら新たな発見がありそうという期待も込めて、少し時間を置いてまた「パーフェクトRuby on Rails 」を読み返してみようと思います。

来週からパーフェクトRuby on Rails輪読会はRailsガイドの輪読会に生まれ変わります。 引き続き運営メンバーとして参加する予定なので良い会にしていきたいな、と思っています。

*1:五十嵐さんは「パーフェクトRuby on Rails 」の著者で、フィヨルドブートキャンプの顧問もされています

brew updateを実行すると、Connection refusedと表示され失敗する

brew updateを実行すると、以下のエラーが表示され落ちてしまった。

$ brew update
fatal: unable to connect to :
[0: ::1]: errno=Connection refused
[1: 127.0.0.1]: errno=Connection refused

Error: Fetching /usr/local/Homebrew failed!

原因はSSHのリモートURLでgitに接続するようにしていたから。 GithubのリモートURLについてはリモートの URL の変更 - GitHub Docs参照。

.gitconfigに以下の2つが定義してあって、このうち[url "git://"]insteadOf = https:/の2行を削除したらbrew updateできた。

[url "https://"]
   insteadOf = git://
[url "git://"]
   insteadOf = https:/

brew updateで落ちたとき、なかなか解決策が見つからず一度homebrewをアンインストールして再インストールしようとした。 すると、再インストール時も以下のエラーで落ちてしまっていた。

$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
Password:
==> This script will install:
/usr/local/bin/brew
/usr/local/share/doc/homebrew
/usr/local/share/man/man1/brew.1
/usr/local/share/zsh/site-functions/_brew
/usr/local/etc/bash_completion.d/brew
/usr/local/Homebrew

Press RETURN to continue or any other key to abort
==> Downloading and installing Homebrew...
fatal: unable to connect to :
[0: ::1]: errno=Connection refused
[1: 127.0.0.1]: errno=Connection refused

Failed during: git fetch origin --force

ただ、再インストール時はbrew updateのときと違って、Failed during: git fetch origin --forceとログに書かれており、git fetchで失敗していると書かれていたため、これがSSHが原因であることの特定に繋がった。 (ので、アンインストールは全くの無駄足ではない...はず)

その後brew updateも実行して無事成功することも確認できた。

.gitconfigの設定を戻すと再び発生するので、もっと良い解決策があれば知りたい...

テスト環境でマイグレーション未実行の場合にminitestとRSpecを実行するとどうなるか調べた

パーフェクト Ruby on Railsの3章でminitestについて以下のように書かれていました。

テスト環境で未実行のマイグレーションファイルがある場合でも、テスト実行時に自動でdb/schema.rbからテスト用のDB設定をロードするようになったため、基本的には作業をする必要はありません。*1

RSpecではどのような動きになるのか気になったので、minitestも含め試してみました。

minitest

  1. rails new todoでTODOリストを作成するサンプルアプリを作成
  2. rails g scaffold todo content:textでコードを生成(ここでテストコードも生成される)
  3. この時点ではまだ一度もマイグレーションを実行していないので、bin/rails testを実行するとMigrations are pending. To resolve this issue, run:rails db:migrate RAILS_ENV=testのエラーになる
  4. bin/rails db:createbin/rails db:migrateを実行。development環境に対する実行なので、テスト環境にはまだマイグレーションは適用されていない
  5. この状態でbin/rails testを実行してみるとテスト実行できた。

    Running via Spring preloader in process 23905 Finished in 0.371335s, 21.5439 runs/s, 26.9299 assertions/s. 8 runs, 10 assertions, 0 failures, 0 errors, 0 skips

RSpec

では、RSpecの場合はどうなるか。minitestで確認したときと同じ状態で、以下のRequestSpecを作成し、実行した。

require 'rails_helper'

RSpec.describe "Tasks", type: :request do
  context "index" do
    it "responds successfully" do
      get tasks_path
      expect(response).to have_http_status(200)
    end
  end
end

結果、実行することができた。

$ bin/rspec
Running via Spring preloader in process 23905
.

Finished in 0.16851 seconds (files took 0.38243 seconds to load)
1 example, 0 failures

RSpecでもminitestのようにdb/schema.rbからテスト用のDB設定をロードするようになっているのかは不明だが、テスト環境でマイグレーションを実行していなくてもテストが実行できることがわかった。

*1:schema.rbが最新ではない時などはマイグレートする必要があります。以降、パーフェクト Ruby on Railsから引用。「ただし、schema.rbが最新ではない時など、ロードした後にも未実行のマイグレーションファイルがある場合はエラーになります。その時はbin/rails db:migrateを実行してschema.rbを最新にするか、またはbin/rails db:migrate RAILS_ENV=testコマンドをつかって手動でテスト環境のマイグレーションを実行してください。」

deviseにおけるStrategyパターン

以下の記事でStrategyパターンの例として紹介されていたdeviseを最近使用したので、どのようにStrategyパターンが使用されているかを調べました。

Rubyでのデザインパターンの使用例を説明する!! - エニグモ開発者ブログ

Strategyパターンとは

ある問題に対するアルゴリズムを他の部分と分離して、状況に応じてアルゴリズムを切り替えられるようにするデザインパターン

deviseにおけるStrategyパターン

deviseはWardenという認証のフレームワークを元に作られています。 Warden::Strategies::Baseのサブクラスを定義することで独自の認証方法を実装することができます。

Warden::Strategies::Base

deviseの場合はDevise::Strategies::BaseWarden::Strategies::Baseを継承しています。

module Devise
  module Strategies
    class Base < ::Warden::Strategies::Base
      (略)
    end
  end
end

さらにその下に、Devise::Strategies::Baseを継承しているDevise::Strategies::Authenticatableクラスが存在します。

module Devise
  module Strategies
    class Authenticatable < Base
      # このクラスが各認証方法が実装されているクラスのベースになる
    end
  end
end

deviseの認証方法が実装されているクラスはさらに一階層下のDatabaseAuthenticatableクラスと、Rememberableクラスです。

module Devise
  module Strategies
    # Default strategy for signing in a user, based on their email and password in the database.
    class DatabaseAuthenticatable < Authenticatable
      # デフォルトの認証方法。DBに登録されているemailとパスワードを使って認証を行う
    end
  end
end
module Devise
  module Strategies
    class Rememberable < Authenticatable
      # cookieの値を使って認証を行う
    end
  end
end

独自の認証方法に切り替える場合は

  • config/initializers/devise.rbに独自のStrategyの設定方法を追加
# hoge_authenticatableという独自のStrategyを追加する
config.warden do |manager|
    manager.default_strategies(scope: :user).unshift :hoge_authenticatable
    manager.strategies.add(:hoge_authenticatable,
                           Devise::Strategies::HogeAuthenticatable)
end
  • 独自のStrategyクラスを作成する
require 'devise/strategies/authenticatable'

module Devise
  module Strategies
    class HogeAuthenticatable < Authenticatable
    end
  end
end

参考