- Ruby / Rails関連
週刊Railsウォッチ: Rails 7リリース、5.2系と6.0.x系のサポート終了時期決定、localhost gemで自己署名証明書生成ほか(20211221前編)
こんにちは、hachi8833です。今年最後の週刊Railsウォッチ前編をお送りします。
🔗Rails: 先週の改修(Rails公式ニュースより)
今回はRails 7に最近マージされたプルリクから見繕いました。
🔗 URL安全でないCSRFトークンを非推奨化
このプルリクでは、
urlsafe_csrf_tokens
をtrueにする設定も非推奨化されるので、Rails 7.1ではこの設定を完全に除去可能。
概要
#39076の続き。Rails 7.0でこの設定オプションを非推奨化する。次のマイナーリリースでこのオプションを削除できるようにする。
その他の情報
これはRails 7.0.0で出す必要はないが、7.1で設定を削除できるようマイナーリリースの間に非推奨にしておきたいので、7-0-stableで出すべき。mainブランチへのプルリクは7.1用になるはずなので、7-0-stableに対して行うことにする。
同PRより
つっつきボイス:「これまでデフォルトでfalse
だったurlsafe_csrf_tokens
を、デフォルトでtrue
にしつつ、今後オフにできなくなるwarningを出すようになった」「こんな設定があるんですね」「URL-safeは、URLとして利用してよい文字だけで構成されているという意味か」「この設定はfalse
にできなくなるようですね: あえてURL安全でないCSRFトークンを使うことはないと思うので大丈夫そう」
# actionpack/lib/action_controller/metal/request_forgery_protection.rb#L95
- self.urlsafe_csrf_tokens = false
+ self.urlsafe_csrf_tokens = true
+
+ singleton_class.redefine_method(:urlsafe_csrf_tokens=) do |urlsafe_csrf_tokens|
+ if urlsafe_csrf_tokens
+ ActiveSupport::Deprecation.warn("URL-safe CSRF tokens are now the default. Use 6.1 defaults or above.")
+ else
+ ActiveSupport::Deprecation.warn("Non-URL-safe CSRF tokens are deprecated. Use 6.1 defaults or above.")
+ end
+ config.urlsafe_csrf_tokens = urlsafe_csrf_tokens
+ end
🔗 エンコーディングが無効なSQLクエリの扱いを改善
- PR: Better handle SQL queries with invalid encoding by casperisfine · Pull Request #43828 · rails/rails
- エンコーディングが無効なSQLクエリの扱いを改善
Post.create(name: "broken \xC8 UTF-8")
上は、書き込みクエリを検出するコードですべてのアダプタが制御不能な方法で失敗する。
このクエリがデータベースコネクションに適切に渡されるようになり、データベースコネクションで処理可能かどうかにかかわらず、より適切な方法で成功または失敗するようになる。
Jean Boussier
同PRより
つっつきボイス:「\xC8
はいかにも無効なUTF-8コードですね」「そういう文字がクエリに混入したときに適切に扱われるようになったのね」
「改修で正規表現に追加されたn
オプションって何だろう?」「Rubyのドキュメントを見るとASCII-8bitエンコーディングにするオプションとありますね」「理屈はよくわからないけど、無効なUTF-8文字の検出用にここだけエンコーディングを変えてるのかな?」「通常のコードでは影響はなさそうですね」
# activerecord/lib/active_record/connection_adapters/abstract_adapter.rb#L68
def self.build_read_query_regexp(*parts) # :nodoc:
parts += DEFAULT_READ_QUERY
parts = parts.map { |part| /#{part}/i }
- /\A(?:[(\s]|#{COMMENT_REGEX})*#{Regexp.union(*parts)}/
+ /\A(?:[(\s]|#{COMMENT_REGEX})*#{Regexp.union(*parts)}/n
end
参考: 正規表現 (Ruby 3.0.0 リファレンスマニュアル)
🔗 Rails 7.0でbutton_to
ヘルパーの挙動変更を明記
- PR: Clarify `button_to` helper changes in Rails 7.0 by nvasilevski · Pull Request #43855 · rails/rails
つっつきボイス:「お、これは先週話題にしたbutton_to
周りの変更の話ですね(ウォッチ20211214)」「リリースノートとアップグレードガイドで明記したそうです」「お〜、button_to("Do a POST", [:do_post_action, Workshop.find(1)])
のようにbutton_to
の第2引数にオブジェクトを配列で渡すとPATCHメソッドとして扱ってくれるようになっていたんですね(#43413)、これは賢い👍」
# guides/source/7_0_release_notes.md#L91
+* `button_to` infers HTTP verb [method] from an Active Record object if object is used to build URL
+
+ ```ruby
+ button_to("Do a POST", [:do_post_action, Workshop.find(1)])
+ # Before
+ #=> <input type="hidden" name="_method" value="post" autocomplete="off" />
+ # After
+ #=> <input type="hidden" name="_method" value="patch" autocomplete="off" />
なお、Railsアップグレードガイド↓には反映済みです。
参考: 2.1 ActionView::Helpers::UrlHelper#button_to
の振る舞いが変更された
-- Rails アップグレードガイド - Railsガイド
Rails 7.0以降の
button_to
は、ボタンURLをビルドするのに使われるActive Recordオブジェクトが永続化されている場合は、patch
HTTP verbを用いるform
タグをレンダリングします。現在の振る舞いを維持するには、以下のように明示的にmethod:
オプションを渡します。
-button_to("Do a POST", [:my_custom_post_action_on_workshop, Workshop.find(1)])
+button_to("Do a POST", [:my_custom_post_action_on_workshop, Workshop.find(1)], method: :post)
または、以下のようにURLをビルドするヘルパーを使います。
-button_to("Do a POST", [:my_custom_post_action_on_workshop, Workshop.find(1)])
+button_to("Do a POST", my_custom_post_action_on_workshop_workshop_path(Workshop.find(1)))
Railsアップグレードガイドより
🔗 Railsメンテナンスポリシーの変更
つっつきボイス:「ガイドのメンテナンスポリシーも更新されました」「お、これは大事なヤツ: Slackにメモしておこう」「Rails 5.2系は来年2022年6月1日でサポート終了なのか〜」「公式なサポート終了時期を事前に宣言してくれるのはありがたい👍」
# guides/source/maintenance_policy.md#L67
-**Currently included series:** `7.0.Z`, `6.1.Z`, `5.2.Z`.
+**Currently included series:** `7.0.Z`, `6.1.Z`.
...
+ NOTE: Rails 5.2.Z is included in the list of supported series until June 1st 2022.
+ NOTE: Rails 6.0.Z is included in the list of supported series until June 1st 2023.
🔗 ファビコンから"shortcut"リンク種別を削除
つっつきボイス:「実はこのプルリクは私が投げたものが7.0に滑り込みでマージされました😊」「お〜ついにRailsコントリビュータじゃないですか」「ファビコンに"shortcut"リンク種別をつける仕様がこんな昔になくなっていたとはね〜」「以下の翻訳記事↓を読み返していて、ふとRails 7ではどうなっているんだろうと思って調べたら、rails new
で生成されるfavicon_link_tag
で"shortcut"リンク種別が付けられていて、類似のプルリクもなかったので、ドキドキしながらプルリク投げました」
icon
より以前はリンク種別shortcut
がよく使用されていましたが、これは非準拠で無視されますのでウェブ作者は今後使用してはいけません。
リンク種別 - HTML: HyperText Markup Language | MDNより
「根拠がはっきりしているプルリクなのでマージしやすいですね👍」「Rails 7リリース直前の慌ただしいときのプルリクでしたが、押し流されなくてよかった😂」
🔗Rails
🔗 Rails 7.0.0
つっつきボイス:「Rails 7出ましたね🎉」「予想より早く出た🎊」「記事のRails 7 Gemfileを見ると、propshaftが入るかと思ったらsprocketsがデフォルトなんですね」「propshaftがデフォルトになる説もありましたがsprocketsになりました」「rails new
で-a propshaft
を指定すれば入れられるのね」
「その代わりimportmap-railsがデフォルトになって、yarnはデフォルトでは入らなくなった」「これを待っていました: rails new
も速くなりました」「つまりnodejsもnode_modulesディレクトリもデフォルトでは不要になった、なるほどこれは脱Webpackerせねば」「rails new
するときのnodeのバージョンを気にしなくてよくなったのは嬉しい👍」
🔗 Rails 7リリース直前のセキュリティ修正
つっつきボイス:「記事の注にも書きましたが↓、セキュリティ修正でdev環境のアクセスに問題が起きて修正のために再々リリースされたという流れでした」「最終的に修正されてよかった😊」「最初のセキュリティ修正と次の修正を手元で反映したら動かなかったので、issueとプルリクをチェックして再々リリースを待ってから記事を出しました」「config.hosts << '.EXAMPLE.com'
を環境変数で設定していたりすると見落としそう」
当初は6.0.4.2/6.1.4.2/7.0.0.rc2がリリースされましたが、
localhost:3000
でアクセスできない問題(#43865)があったので6.0.4.3/6.1.4.3/7.0.0.rc3がリリースされました。しかしlvh.me:3000
のようにポート番号を指定できない問題(#43864)があったので、最終的に6.0.4.4/6.1.4.4がリリースされました。
同記事より
🔗 wicked: Railsでウィザードを作るgem(Ruby Weeklyより)
参考: Wizard-ify Your Rails Controllers with Wicked
つっつきボイス:「Railsでいわゆるウィザード的なインターフェイスを構築するのに使うgemだそうです」「ウィザード風のUIを構築するgemは他にもありますね」「欲しい人は多いでしょうね」「ウィザード風に作ろうとするとRails wayから外れてしまいがちなんですよ」
参考: ウィザード (ソフトウェア) - Wikipedia
「こうやってステップを書いてビューを切り替えていく感じなのはなかなかよさそう↓」
# 同リポジトリより
class AfterSignupController < ApplicationController
include Wicked::Wizard
steps :confirm_password, :confirm_profile, :find_friends
def update
@user = current_user
case step
when :confirm_password
@user.update_attributes(user_params)
end
sign_in(@user, bypass: true) # needed for devise
render_wizard @user
end
private
def user_params
params.require(:user)
.permit(:email, :current_password) # ...
end
end
app/
views/
controller_name/
first.html.erb
second.html.erb
# ...
「途中で画像ファイルを添付したりしてもうまく扱えるかな?」「それ面倒そうですね」「ステップバイステップのウィザードの実装はそういう部分が大変なんですよ: テキストならhiddenフィールドに埋めたりできますけど、途中にファイル添付が入ると急に難易度が上がるし、途中でパスワードをhiddenフィールドに入れ直すのも避けたい」
「しかしwicked(邪悪な)とはすごい名前」「魔法使いを形容するのによく使われる言葉だからでしょうね」
オズの魔法使いに登場する「西の悪い魔女」がWicked Witch of the Westだったり、レイ・ブラッドベリのファンタジー小説「何かが道をやってくる」の原題が「Something Wicked This Way Comes」だったのを思い出します。
参考: オズの魔法使い - Wikipedia
参考: Something Wicked This Way Comes (novel) - Wikipedia
🔗 spyke: her gemの改良版(Ruby Weeklyより)
つっつきボイス:「spykeは、ウォッチで何度か話題になったher gemのオルタナだそうです(ウォッチ20211108)」「たしかに、このコンフィグでアダプタやパーサーを指定しているあたりがherっぽい↓」
# 同リポジトリより
# config/initializers/spyke.rb
class JSONParser < Faraday::Response::Middleware
def parse(body)
json = MultiJson.load(body, symbolize_keys: true)
{
data: json[:result],
metadata: json[:extra],
errors: json[:errors]
}
end
end
Spyke::Base.connection = Faraday.new(url: 'http://api.com') do |c|
c.request :json
c.use JSONParser
c.adapter Faraday.default_adapter
end
「spykeのREADMEによると、herはいいgemだけど新しくないのとパフォーマンスに難があるのでspykeを作ったそうです」「あとherはプログラムの構成上なのか、サイズが割と大きいですね」「herの最初のリリースを見てみたら2013年頃からあるみたい」「その頃からherを使ってたな〜」
🔗 localhost: pumaですぐ使える自己署名証明書gem
つっつきボイス:「今日のWebチーム内発表で話題になっていたgemです」「これは何ですか?」「このgemだけでローカル開発環境にSSL/TLSアクセスを簡単に組み込めます」「へ〜!」
「最近はローカル環境でもhttpsでリッスンしないと動かせないようなコードが増えてきていて、特にブラウザのAPIによってはGPSの現在地取得のようにhttpだとアクセスできないものもあったりするので、そういうのをローカルで検証するときに便利」「なるほど」
参考: Webブラウザで現在地情報を正しく取得できない場合の原因と対策:Tech TIPS - @IT
「localhost gemの実装はシンプルですが、pumaでも公式にサポートされているのがポイント高い↓」「手順までちゃんとREADMEに書かれてるんですね」
「ローカルでhttps接続するときに大変なのは自己署名証明書を作る部分: 証明書に署名するために自分用の認証局を作らないといけないし、CSR(Certificate Signing Request)を埋めるためにcommon nameなども入力する必要があるとか、作業が多いんですよ」「あ〜たしかに」「こういう自動化ができるとありがたい」
「そういう作業をopenssl
コマンド手打ちでやるのは大変すぎるので、一般にはubuntuなどのパッケージにも入っているmkcertというツールを使ってやることが多いですね↓」「mkcert使ったことあったかも」「mkcertは証明書をデフォルトでユーザーのホームディレクトリの下に保存するといった細かいところがよくできている」「そういうの大事ですよね」
「ちなみにlocalhost gemは鍵ファイルの作成が不要で、証明書を実行時に動的に作ってくれるのでさらに便利👍」「お〜」
前編は以上です。
バックナンバー(2021年度第4四半期)
週刊Railsウォッチ: RailsでGDPRに対応する、stateful_enum gem、rubyzip 3.0ほか(20211214前編)
- 20211207後編 改訂2版『プロを目指す人のためのRuby入門』、『研鑽Rubyプログラミング β版』ほか
- 20211206前編 sanitize_sql_likeは重要、X-XSS-Protectionヘッダーのデフォルト変更、kredis gemほか
- 20211201後編 Railsで「Read Model」を使う、Ruby Prize 2021受賞者決定、pru gemほか
- 20211129前編 フォームヘルパーの改修、Railsの監査ログgem比較、DHHとimport-mapほか
- 20211116後編 Ruby Struct入門、書籍『進化的アーキテクチャ』、AWS Web問題集ほか
- 20211115前編 Rails 7がRuby 3.1のClass#descendantsに対応、GitHub Issue風ファイルアップローダほか
- 20211110後編 JSON.parseの機能、Opal 1.3、async gem、Linuxコマンドチートシートほか
- 20211102後編 2021年度Rubyアソシエーション開発助成、Rails REST APIレベルで楽観的ロックほか
- 20211101前編 Rails 7アセットパイプライン解説記事、ロジックをapp/operatorsで整理ほか
- 20211026後編 YJITがRuby 3.1向けにマージ、ripperのドキュメント化、crontabの罠ほか
- 20211025前編 insert_allやupsert_allのタイムスタンプ自動更新、rails/contextsにロジックを置くほか
- 20211019後編 ruby/debugをChromeでリモートデバッグ、Rubyアプリの最適化ほか
- 20211018前編 Railsリポジトリで進行中のPropshaft、inverse_ofを自動推論ほか
- 20211012後編 Ruby 3.1にYJITマージのプロポーザル、Rubyのmagic historyメソッド、JSのPartytownほか
- 20211011前編 ServerTimingミドルウェア追加、paramsで数値キーを許可、Railsで多要素認証ほか
- 20211006後編 ruby/debug 1.2.0リリース、Railsにはthorが入っている、tendejitほか
- 20211004前編 Rails 7でbyebugがruby/debugに変更、GitHub Codespacesをサポートほか
今週の主なニュースソース
ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSやruby-jp SlackやRedditなど)です。
週刊Railsウォッチについて
TechRachoではRubyやRailsなどの最新情報記事を平日に公開しています。TechRacho記事をいち早くお読みになりたい方はTwitterにて@techrachoのフォローをお願いします。また、タグやカテゴリごとにRSSフィードを購読することもできます(例:週刊Railsウォッチタグ)