Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

週刊Railsウォッチ: Ruby on Jets 6.0がRailsをサポートほか(20240620後編)

こんにちは、hachi8833です。

週刊Railsウォッチについて

  • 各記事冒頭には🔗でパーマリンクを置いてあります: 社内やX.comでの議論などにどうぞ
  • 「つっつきボイス」はRailsウォッチ公開前ドラフトを(鍋のように)社内有志でつっついたときの会話の再構成です👄
  • お気づきの点がありましたら@hachi8833までメンションをいただければ確認・対応いたします🙏

TechRachoではRubyやRailsなどの最新情報記事を平日に公開しています。TechRacho記事をいち早くお読みになりたい方はTwitterにて@techrachoのフォローをお願いします。また、タグやカテゴリごとにRSSフィードを購読することもできます(例:週刊Railsウォッチタグ)

🔗Rails: 先週の改修(Rails公式ニュースより)

🔗 CSPのwasm-unsafe-evalでWasmモジュールの読み取り・実行を許可

動機/背景

Content Security Policy(CSP)の'wasm-unsafe-eval'を使うと、安全でないJavaScriptの実行を'unsafe-eval'で許可しなくても、WebAssemblyモジュールの読み込みと実行を許可できるようになる。

定義されているマッピングによって、config/initializers/content_security_policy.rb内の設定を、ポリシーのキーワードを表すシンボルで定義可能になる。wasm-unsafe-evalキーワードが導入されたのは、RailsでCSP機能を追加した#31162よりも後なので、現在のマッピングリストには含まれていない。

詳細

このプルリクは、CSPキーワードマッピングを変更してwasm-unsafe-evalオプションを追加する。

同PRより


つっつきボイス:「WebAssemblyのための'wasm-unsafe-eval'というCSPがあるんですね、なるほど」

参考: 安全ではない WebAssembly の実行 -- CSP: script-src - HTTP | MDN

Content-Security-Policy: script-src 'wasm-unsafe-eval'

🔗 pretty_printの振る舞いをinspectに近づくよう修正

pretty_printattribute_for_inspectを呼び出さないことを発見した。

このプルリクは、pretty_printの振る舞いを、inspectと同じように("raw"属性を使わずに)attribute_for_inspectを呼び出すよう修正する。なお、開発者はモデルのクラスでこれを上書きできる。

この振る舞いをカバーするテストはtest_pretty_print_with_overridden_attribute_for_inspectである。

完全を期すため、inspectにも同様のテストを追加したが、コード変更前でもtest_inspect_with_overridden_attribute_for_inspectのテストはパスした。

新しい振る舞いを反映するために、他のテストもいくつか更新が必要だった。pretty_printの振る舞いはinspectに似ているので、これは良いことだと思う(例: [FILTERED]は引用符なしでも両方で同じように出力されるようになった)。

Dateオブジェクトもinspectpretty_printの両方で同じフォーマットで出力されるようになった。

同PRより


つっつきボイス:「あ〜、pretty_printinspectの振る舞いが微妙に違ってることがたまにありますね」「よくぞ見つけた感じ」

参考: Rails API pretty_print -- ActiveRecord::Core

# activerecord/lib/active_record/core.rb#L739
    def pretty_print(pp)
      return super if custom_inspect_method_defined?
      pp.object_address_group(self) do
        if @attributes
          attr_names = attributes_for_inspect.select { |name| _has_attribute?(name.to_s) }
          pp.seplist(attr_names, proc { pp.text "," }) do |attr_name|
            attr_name = attr_name.to_s
            pp.breakable " "
            pp.group(1) do
              pp.text attr_name
              pp.text ":"
              pp.breakable
-             value = _read_attribute(attr_name)
-             value = inspection_filter.filter_param(attr_name, value) unless value.nil?
-             pp.pp value
+             value = attribute_for_inspect(attr_name)
+             pp.text value
            end
          end
        else
          pp.breakable " "
          pp.text "not initialized"
        end
      end
    end

🔗 ActiveRecord::Relation.readonly?を追加

  • ActiveRecord::Relation.readonly?を追加

リレーションがreadonlyとマーキングされているかどうかを反映する。

Theodor Tonum
同Changelogより

リレーションがreadonlyかどうかを示す。

動機/背景

リレーションがreadonlyかどうかをチェックするドキュメント化されたAPIは現在ない。回避策は、レコードを読み込んでreadonly?をチェックするか、ドキュメント化されていないreadonly_valueにアクセスすることになる。

リレーションをreadonlyとしてマーキング可能にすることで、何をレンダリングするかを示す情報として利用可能になる。この変更によって、そうしたユースケースがシンプルになる。

詳細

ActiveRecord::Relation#readonly?を追加する。これは、含まれるレコードに対してActiveRecord::Base#readonly?と同様に振る舞う。
同PRより


つっつきボイス:「Active Recordのリレーションがリードオンリーかどうかを、レコードを読み込む前にリレーション上でチェックできる: こういうのが欲しくなる場合もありそう👍」

# activerecord/lib/active_record/relation.rb#1264
    def readonly?
      readonly_value
    end

🔗 AllowBrowser:modernを修正

動機/背景

#50505で新しくAllowBrowser機能が追加されたことで、アプリケーションでブラウザの最小バージョンを設定可能になった。特定の機能リストを必須とする:modernバージョンセットが定義・ドキュメント化され、そのオプションが新しいアプリのデフォルト設定に追加されるようになる。

このプルリクは、:modernで2箇所小さな修正を行う。1つはバージョンの修正、もう1つはドキュメントの修正。

詳細

  1. 24264baでは、modernのブラウザバージョンが、必須機能の説明と一致するよう修正する。具体的には、CSS nestingはChrome 120とOpera 106まではサポートされない(caniuseMDN

  2. ff02912は、badgingをドキュメントの必須機能リストから削除する(この仕様はどのブラウザでも完全には実装されていないため: caniuseMDN

追加情報

個人的には、このAllowBrowser機能がアプリの新しいデフォルトとしてふさわしいとは思えないが、今後提供されるのであれば目的は達せられるはず。

お楽しみとして自分のノートPCでUserAgent.parse.browserのベンチマークを取ってみたところ、40msecで実行され、予想よりは高速だった。ただしランタイムのrequire "useragent"によって、最初のリクエストでは30msec余分にかかった。

useragent gemが最後に更新されたのは5年前であり、ブラウザ認識コードはどれも7〜9年前のものである。Edge(2015)を認識できない:modernは不適切と思われる。このgemにはart19によるfork版もあり、こちらはEdgeを認識できるが、他にも54種類のブラウザが追加されているため行数は4倍も増えており、requireに90msecもかかるので、両者の中間ぐらいのものがあるとよさそう。

Lmodern機能の各機能をサポートするブラウザバージョンのリストをGoogle Spreadsheetで作成した。要約すると、badgingとCSS nestingは、(CSSの:hasのサポートが遅れている)Firefoxを除く、すべての主要ブラウザにおいて最も制約の厳しい要件である。
同PRより


つっつきボイス:「AllowBrowserは少し前に入った機能でしたね(ウォッチ20240123)」「CSS nestingとBadgingが現状に即してなかったのか」「: modernに含めるブラウザの定義を修正したんですね」「Badgingって初めて知りました」

参考: & 入れ子セレクター - CSS: カスケーディングスタイルシート | MDN
参考: Badging API - Web API | MDN

ウェブ開発者は、よく状態を表すために文書のファビコンやタイトルを更新します。Badging API は、ユーザーエージェントが解釈でき、UI の他の部分に合う形で表示できる方法を提供することで、状態を表示するためのより上品な方法を提供します。
Badging API - Web API | MDNより

「ちなみにx.com(旧Twitter)は、割と前からIEなどの古いブラウザで開くと"このブラウザは現在サポートされていません"と言われちゃいますね」「そうだったんですね😳」「ちょっと細かいけど、CSS nestingはまだ新しい分、古いAndroid携帯のChromeで動かないとかあるかも」

参考: “twitter.com”の「IE 11」と旧UIのサポートが終了 ~「GoodTwitter」拡張機能などに影響 - やじうまの杜 - 窓の杜

🔗Rails

🔗 Rails Guidesの次のレビュー募集(Rails公式ニュースより)


つっつきボイス:「Rails 7.2では以下のドキュメント↓がメジャー更新されましたけど、今度はおそらくRails 8を目標に上のドキュメントのメジャー更新のレビューを一般から募っているそうです」「マイグレーションは深いテーマなので書くこといっぱいあるでしょうね👍」

🔗 1ファイルで動くRailsアプリケーションを作った(Ruby Weeklyより)


つっつきボイス:「Ruby Weeklyの見出しには一味違う的なことが書かれていました」「お遊び的に1ファイルのRailsアプリケーションを作る記事はときどき見かけるけど、これはGemfileやスキーマの定義↓も含めて1ファイルになっていて、rackup app.ruすれば動くようになっているんですね、ちょっと面白い😋」

# 同記事より抜粋
# frozen_string_literal: true
require 'bundler/inline'

gemfile(true) do
  source 'https://rubygems.org'

  gem 'rails', '~> 7.0.4'
  gem 'sqlite3'
end

require 'rails/all'
database = 'development.sqlite3'

ENV['DATABASE_URL'] = "sqlite3:#{database}"
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: database)
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Schema.define do
  create_table :posts, force: true do |t|
  end

  create_table :comments, force: true do |t|
    t.integer :post_id
  end
end
...

🔗 Ruby on Jets 6.0がリリース(Ruby Weeklyより)


つっつきボイス:「Ruby on Jets(ウォッチ20230608)、着々とバージョンアップされていますね🎉」「Jetsで作った超シンプルなアプリを業務で運用していて、数年間ノートラブルで動いています👍」

「今回の目玉はRailsのサポートとありますね」「DockerイメージをビルドしてAWS Lambdaにデプロイするようになって、Rails以外にSinatraやHanamiを含む任意のRackアプリをデプロイできるようになっているので、Rackインターフェイスをサポートしたようですね」「なるほど」「prewarmingでコールドスタートを高速にするあたりは以前取り上げたLamby(ウォッチ20230705)に似ているかも: 割と手広く改修されている感じ」

「自分が知っているバージョンではアクションの数だけLambda Functionがデプロイされていたと思うので、そのままコールドスタートしようとすると効率が悪そうな気がする」「あ、そういうふうになっていたんですか」「そのあたりをどう工夫しているか後で追いかけてみようかな」

🔗Ruby

🔗 RBSにRuboCopをかける


つっつきボイス:「RBS用のRuboCopは欲しいヤツ」「rubocop -aで修正されるのは嬉しい😂」「RuboCopの仕事がPrittierみたいに増えてきている感ありますね」

ksss/rubocop-on-rbs - GitHub

🔗 Ruby技術者認定試験(Silver/Gold対応) 公式テキスト


つっつきボイス:「新しい公式テキスト出た🎉」「Ruby技術者認定試験の3.0は2022年10月から始まっていたけど、公式の教科書が3.0に対応していなかったのが追いついたということですね👍」

参考: 最短突破 Ruby技術者認定試験(Silver/Gold対応) 公式テキスト:書籍案内|技術評論社

🔗言語/ツール/OS/CPU

🔗 DevToysとBusyBox


つっつきボイス:「お、DevToysが新しくなったんですね: 頻繁に使うわけではないけど、個人的にはCLI対応が嬉しいかも👍」「DevToysとは別に、1つのパッケージで色々なツールが内包されているLinux用ソフトウェアがありましたけど何でしたっけ?」「そうそう、BusyBoxですね(ウォッチ20191210): サーバー管理とかで使えるLinuxコマンドがワンバイナリに入っているので、制約の多い環境を整えるのに便利」「いずれにしろBusyBoxとDevToyは方向性が違うでしょうね」

参考: BusyBox - Wikipedia

「ツールと言えば、DHHがこんなツールを発表していました↓」「Omakub?」「どうやらOmakase Ubuntuの略っぽいです: 英語圏でOmakaseという言葉が流行ってて、それをもじった造語もよく作られているみたいですね」「ざっと見た感じ開発環境のセットアップコマンド的なものかな🤔」

参考: 日本の「おまかせ」が海外でブーム!英語で説明してみよう | English Lab(イングリッシュラボ)┃レアジョブ英会話が発信する英語サイト


後編は以上です。

バックナンバー(2024年度第2四半期)

週刊Railsウォッチ: Rails 8からPropshaftがアセットパイプラインのデフォルトにほか(20240619前編)

ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSやruby-jp SlackやRedditなど)です。

Rails公式ニュース

Ruby Weekly


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。