Rails Tutorials 2週目を終えて

第3版となりパワーアップしたのを知ったので
9月中頃からちょっとずつ実施してきた Rails Tutorials ですが
1ヶ月ちょっとで終えることができました(ちょっと掛かりすぎた)。

感想

改めてやってみた感想ですが、Railsやる人なら1回くらいやっといて損はない内容ですね。
書いた人もすごいし、訳した人もすごいわ。
 
時間的には、後半のchapmter のvolumeが少し大きいので、平均すると2時間ぐらい掛かっていたような気がします。
全体のボリュームとしては、1日1時間で約1か月ぐらいのスケジュール感で臨むと良いかもしれません。
 
内容としては、やはりテスト周りの充実度は高くて良いです。
minitestの書き方を知れます。minitestはあまり書いたことがなかったのでとても勉強になりました。
 
当初、herokuの作業は初心者には不要かなと思ったのですが
メール配信したり、fog経由で画像ファイルをs3に保存することが体験できるので
可能であればやっておいた方が良いと思いました。
 
ただ、通常production環境では assets precompile が必要ですが、
herokuでは不要だったりするので、初心者は誤解する可能性があります(そこは躓いて学べば良いだけですが)。
最後に軽めのSQLのチューニングの話がありましたが、eager loading (N+1)の話などもあっても良いかなと 思いましたが、この辺りは次のstepでしょうか。
 
あと、内容とは関係ないですが、
commitの粒度が大きいと感じました。もう少し小分けにcommitすべきかな。
 
また、第3版からCloud9を使うようになったのですが
これ自体は結構使いやすく、これが無料というのはすごいと思いながら触っていました。
windows ユーザなどは良いかもしれません。
最後までCloud9を使いましたが、個人的には若干のレイテンシを感じるので、
環境が容易に整えれる人であれば、local の方が良いかなという印象。

Rails Tutorial 第3版 第12章

今回は has_many :through の実例が学べます。
following, followers, followed など間違えやすいので整理してから進めると良いです。

Ruby on Rails チュートリアル:実例を使って Rails を学ぼう の2周目です。
第12章 ユーザーをフォローする | Rails チュートリアル

第12章 ユーザーをフォローする

Ajax時の設定

#config/application.rb
config.action_view.embed_authenticity_token_in_remote_forms = true

演習

CGI.escapeHTMLでHTMLのエスケープ処理を使っている点に注目して、
なぜこれが必要なのか考えてみてください。

これは、Railsアポストロフィなどの記号を実体参照として変換してくれているかで
テスト時にはそこを考慮しないとエラーとなります。

test/fixtures/microposts.yml

tone:
  content: "I'm sorry. Your words made sense, but your sarcastic tone did not."

 
ようやく終わった。
2週目なのでもっと早くできるかと思いましたが、結構かかりました。
まとめでも書いてみようかしら。

RailsのsorceryでBrute force対策を行う

認証部分だけですが、ログインロック機能がお手軽に実装できます。
moduleとして組み込んで一部設定変更すればokでした。
Brute force protection · Sorcery/sorcery Wiki

ざっくり

実施方法は、基本githubを見てもらえれば良いです。

rails g sorcery:install brute_force_protection --only-submodules

して、migrateしたのち、以下を設定すれば終了。
 
config/initializers/sorcery.rb

    # -- brute_force_protection --
    # Failed logins attribute name.
    # Default: `:failed_logins_count`
    #
    # user.failed_logins_count_attribute_name =


    # This field indicates whether user is banned and when it will be active again.
    # Default: `:lock_expires_at`
    #
    # user.lock_expires_at_attribute_name =


    # How many failed logins allowed.
    # Default: `50`
    #
    user.consecutive_login_retries_amount_limit = 10


    # How long the user should be banned. in seconds. 0 for permanent.
    # Default: `60 * 60`
    #
    # user.login_lock_time_period =

    # Unlock token attribute name
    # Default: `:unlock_token`
    #
    # user.unlock_token_attribute_name =

    # Unlock token mailer method
    # Default: `:send_unlock_token_email`
    #
    # user.unlock_token_email_method_name =

    # when true sorcery will not automatically
    # send email with unlock token
    # Default: `false`
    #
    # user.unlock_token_mailer_disabled = true

    # Unlock token mailer class
    # Default: `nil`
    #
    # user.unlock_token_mailer = UserMailer

連続10回失敗するとロックが掛かり、1時間で解除されます。

補足

ログイン時にロックされていた場合はメッセージを変えたいところですが 実現するには、用意されている user.locked? メソッドを使うと良さそうです。
注意事項としては、session controller などでloginメソッドを使用していると
思われますが、アカウントロック時は、loginメソッドがnilを返すので
別途キー項目で検索する必要があります。

    if @user = login(params[:session][:email], params[:session][:password])
      redirect_back_or_to(root_url, success: "ログインしました!")
    else
      user = User.find_by_name(params[:session][:email])
      msg = user&.locked? ? "アカウントがロックされました" : "ログイン失敗"
      flash.now[:warning] = msg
      render :new
    end

See Also