- Ruby / Rails関連
週刊Railsウォッチ: method_missingの引数を'...'に置き換え、JRuby Prism、Sidekiqのしくみほか(20240306)
こんにちは、hachi8833です。
超久しぶりに対面でのつっつき会を開催できました😂。
🔗Rails: 先週の改修(Rails公式ニュースより)
🔗 assert_broadcasts
がブーリアンの代わりにブロードキャスト済みのメッセージを返すようになった
assert_broadcasts
が、ブロードキャスト済みのメッセージを返すようになった。
これにより、ブロードキャスト済みメッセージのさらなる分析がやりやすくなる。message = assert_broadcasts("test", 1) do ActionCable.server.broadcast "test", "message" end assert_equal "message", message messages = assert_broadcasts("test", 2) do ActionCable.server.broadcast "test", { message: "one" } ActionCable.server.broadcast "test", { message: "two" } end assert_equal 2, messages.length assert_equal({ "message" => "one" }, messages.first) assert_equal({ "message" => "two" }, messages.last)
Alex Ghiculescu
同Changelogより
このプルリクは#47025での
assert_email
の改修と同様、Action Cableのassert_broadcasts
がブロードキャスト済みのメッセージを返すようになった。これは以下のようにさらに分析可能になる。messages = assert_broadcasts("test", 2) do ActionCable.server.broadcast "test", { message: "one" } ActionCable.server.broadcast "test", { message: "two" } end assert_equal 2, messages.length assert_equal({ "message" => "one" }, messages.first) assert_equal({ "message" => "two" }, messages.last)
これは、ブロードキャストされるメッセージ数が多い場合や、データの一部の要素だけを照合したい場合に有用。
assert_broadcast_on
はどちらのシナリオでもうまくいかない。同PRより
つっつきボイス:「ブロードキャスト済みのメッセージを返す前のことは書かれていなかったんですが、以前はtrue/false
を返していたんですね」「アサーションでブロードキャストメッセージの内容も調べられるのはいい👍」
参考: Rails API assert_broadcasts
-- ActionCable::Channel::TestCase::Behavior
🔗 テストよもやま話
「ところで、今はRailsアプリのテストでminitestとRSpecとどちらがよく使われているんでしょうか?」「今やってるプロジェクトはRSpec」「個人アプリでminitest使ってます」「Rails作者のDHHがRSpecが好きでないというのは昔から有名で、他の人が使うのはいいけど自分は使いたくないというスタンスですね」
「一般的にですけど、ライブラリやフレームワークを対象とするテストはminitestみたいな比較的シンプルなアサーションの方が望ましいことが多いでしょうね: 一方、特にビジネスユースケースを伴うアプリだとRSpecのcontext
やdescribe
のようなものがビジネスを説明するうえでしっくりくると思いますし、特にcontext
と言えばビジネスコンテキストを連想しやすいしステートを持っている感じを出せますね」「なるほど」「もちろんライブラリやフレームワークにもステートがあることもありますけど、一般にライブラリやフレームワークはどちらかというとステートがあまり前面に出てこないような印象があるのでminitestを好む気持ちもわからなくもないかな: とはいえRailsぐらい大規模になるとそうもいかないでしょうけど」「rails new
のオプションを網羅するテストなんかはベタ書きだと大変そうですね」
「ところでminitestはパラレル実行できるけどRSpecはそのままだとパラレルにできないんでしたっけ?」「大昔はrrrspecで分散実行したりしていたこともありましたけど、もうだいぶ前からparallel_testsでパラレル実行できますよ」「あ、知りませんでした😅」
参考: Rails - Rspec で paralells test を利用して並列処理する ( create / migrate / prepar
参考: さようならrrrspec、いままで速度をありがとう - 弥生開発者ブログ
🔗 has_one
関連付けの自動保存のバグを修正
外部キー属性が変更されていない場合に設定される
has_one
関連付けの自動保存を修正。この振る舞いは
belongs_to
の自動保存とも一貫しておらず、外部キー属性がread-onlyとマーキングされている場合にActiveRecord::ReadOnlyAttributeError
などの意図しない副作用が発生する可能性がある。Joshua Young
同Changelogより
動機/背景
修正: #50897
類似プルリク: #46759
詳細
ActiveRecord::AutosaveAssociation#save_has_one_association
が、子レコード上の外部キー属性が変更された場合にのみ外部キー属性を更新するよう修正。これにより、belongs_to
関連付けの振る舞いと一貫するようになり、属性が変更されなかった場合にActiveRecord::ReadOnlyAttributeError
が発生しないようになる。
同PRより
つっつきボイス:「has_one
ってhas_many
やbelongs_to
と比べてあまり使われてない分バグが見つかりやすいんですよね」「たいていhas_many
やbelongs_to
の方が圧倒的に注目されていますよね」「readonlyな属性を変更せずに保存したらエラーになるのはバグ」「修正はこれだけですね↓」
# activerecord/lib/active_record/autosave_association.rb#L442
def save_has_one_association(reflection)
association = association_instance_get(reflection.name)
record = association && association.load_target
if record && !record.destroyed?
autosave = reflection.options[:autosave]
if autosave && record.marked_for_destruction?
record.destroy
elsif autosave != false
primary_key = Array(compute_primary_key(reflection, self)).map(&:to_s)
primary_key_value = primary_key.map { |key| _read_attribute(key) }
if (autosave && record.changed_for_autosave?) || _record_changed?(reflection, record, primary_key_value)
unless reflection.through_reflection
foreign_key = Array(reflection.foreign_key)
primary_key_foreign_key_pairs = primary_key.zip(foreign_key)
primary_key_foreign_key_pairs.each do |primary_key, foreign_key|
- record[foreign_key] = _read_attribute(primary_key)
+ association_id = _read_attribute(primary_key)
+ record[foreign_key] = association_id unless record[foreign_key] == association_id
end
association.set_inverse_instance(record)
end
saved = record.save(validate: !autosave)
raise ActiveRecord::Rollback if !saved && autosave
saved
end
end
end
end
🔗 where.associated
のバグを修正
この修正によって、スコープ内の既存のJOINに基づいて、適切なJOIN種別(INNER JOINまたはLEFT OUTER JOIN)を用いて関連付けがJOINされるようになる。
これにより、既存のJOIN種別が意図せずオーバーライドされることを防ぎ、一貫したSQLクエリが生成されるようになる。
例:
# `associated`では`JOIN`ではなく`LEFT JOIN`が使われる Post.left_joins(:author).where.associated(:author)
Saleh Alhaddad
同Changelogより
動機/背景
Railsの現在の
where.associated
メソッドは、関連付けられたレコードをinner join
でフィルタすることしかできず、クエリで既存のJOIN種別がオーバーライドされる可能性がある。この修正によって、スコープ内の既存のJOINに基づいて、適切なJOIN種別(INNER JOINまたはLEFT OUTER JOIN)を用いて関連付けがJOINされるようになる。これにより、既存のJOIN種別が意図せずオーバーライドされることを防ぎ、一貫したSQLクエリが生成されるようになる。例:
User.left_outer_joins(:orders).where.associated(:orders).count
修正前のクエリ:
SELECT COUNT(*) FROM "users" INNER JOIN "orders" ON "orders"."user_id" = "users"."id" WHERE "orders"."id" IS NOT NULL
問題修正後のクエリ:
SELECT COUNT(*) FROM "users" LEFT OUTER JOIN "orders" ON "orders"."user_id" = "users"."id" WHERE "orders"."id" IS NOT NULL
この機能強化によって、関連付けられたデータへのクエリを開発者がさらに柔軟に実行できるようになり、以下のようなシナリオが容易になる。
- 投稿の一部に著者が割り当てられていない場合でも、著者付きの投稿リストを取得する(
left_joins
を利用)- ユーザーが紐づけられていない孤立コメントを含めて、特定ユーザーと関連付けられているコメントリストを取得する(複数のJOIN種別を利用)
詳細
このプルリクにおける重要な改善点は、スコープ内の既存のJOINに基づいて、適切なJOIN種別(INNER JOINまたはLEFT OUTER JOIN)を用いて関連付け同士がJOINされるようになることである。これによって、既存のJOIN種別が意図せずオーバーライドされることを防ぎ、生成されるSQLクエリの一貫性が高まる。
追加情報
この改良は、さまざまなフォーラムやディスカッションでRails開発者によって明らかにされた共通要件に基づいている。これと類似した機能は特定の有名なORM拡張でも普及しており、その有用性が強調されている。この実装は、既存のコードベースの明確さと一貫性を維持するように作られている。
注: この説明はドラフトであり、各自の実装の詳細やプロジェクトの事情に合わせて調整が必要。
FYI: このプルリクがマージされたら、別のプルリクで
missing
メソッドをチェックしてこの問題を修正する予定。(メモ: パフォーマンスは修正前後でほとんど変わらないらしい)
同PRより
つっつきボイス:「このバグは、LEFT OUTER JOINだったクエリがassociated
でINNER JOINに変わったりするのを修正したということですね」「associated
って、missing
の逆のメソッドじゃなかったかな?」「そういえばありましたね↓」「Rails 7に入った、関連先に物理レコードが存在するものだけを取ってくる機能だった(ウォッチ20201208)」「missing
はもっと前からありますね」
参考: Rails API missing
-- ActiveRecord::QueryMethods::WhereChain
「associated
やmissing
って本編コードでは普通はあまり使わないはずのもので、ありそうな使い方としてはproductionデータで何らかの原因でバリデーションをすり抜けて、ないはずのレコードがあったり、あるはずのレコードがないといった異常データをメンテナンスするときの利用を主に想定しているんじゃないかな」「ふむふむ」「belongs_to
などでdependent: :nullify
とかoptional: true
とかを使ったり、あるいは生SQL使ってたりするとそういう孤立レコードができる可能性があるけど、そうでもなければ普通はできないはずなんですよね」「missing
を使うことがあるとすれば、トランザクション内で一時的にできる孤立レコードをバッチ更新したいときにmissing
で孤立レコードを取り直すとかですかね」「そういう場合はありうるし、やってはいけないわけではないけど、なるべくならActive Recordで1個ずつ正当な方法で処理していく方が望ましいでしょうね」
「ところで、サンプルコードでLEFT OUTER JOINした後にassociated
でまたLEFT OUTER JOINするのってどういうシチュエーションなのかよくわからないです↓」「これは単なる修正内容を説明するときのクエリなんじゃないかな」「left_outer_joins
がassociated
を通すとINNER JOINになってしまうのはよろしくないので元のLEFT OUTER JOINを変えないように修正したということでしょうね」
User.left_outer_joins(:orders).where.associated(:orders).count
「associated
やmissing
は主にそういうデータ不整合を解消するときに使う印象があるかな」
🔗 リダイレクトのクエリパラメータのログ出力にconfig.filter_parameters
が効くようになった
元の#21045は8年前のプルリクだそうです。
リダイレクト先のパラメータをフィルタする機能を追加。
config.filter_parameters
を用いてフィルタが必要なものとマッチさせる。
結果は以下のようになる。Redirected to http://secret.foo.bar?username=roque&password=[FILTERED]
修正: #14055
Roque Pinel、Trevor Turk、tonytonyjan
同Changelogより
つっつきボイス:「リダイレクトしたときにリダイレクト先のクエリパラメータがそのままログに出力されていたのね」「リダイレクトのURLにもconfig.filter_parameters
のフィルタが効くように修正したんですね」「そもそもログインで?username=ユーザー名&password=パスワード
みたいにクエリパラメータに露出させる書き方って普通しないと思いますけどね」「ですよね」「ごくたま〜に見かけなくもないですけど」「秘密でも何でもないワンタイムのトークンぐらいだったらありますね」
# actionpack/lib/action_dispatch/http/filter_redirect.rb#L5
module ActionDispatch
module Http
module FilterRedirect
FILTERED = "[FILTERED]" # :nodoc:
def filtered_location # :nodoc:
if location_filter_match?
FILTERED
else
- location
+ parameter_filtered_location
end
end
...
+
+ def parameter_filtered_location
+ uri = URI.parse(location)
+ unless uri.query.nil? || uri.query.empty?
+ uri.query.gsub!(FilterParameters::PAIR_RE) do
+ request.parameter_filter.filter($1 => $2).first.join("=")
+ end
+ end
+ uri.to_s
+ end
参考: § 3.2.33 config.filter_parameters
-- Rails アプリケーションの設定項目 - Railsガイド
「デフォルトのフィルタは部分一致なので、以下の名前を部分的にでも含むものはフィルタで除外されるようになっていますよね↓」
# Railsガイドより
Rails.application.config.filter_parameters += [
:passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
]
「この種のフィルタは慎重な方に倒すのが基本ですね: たとえばログに個人を特定できるような情報やセンシティブな情報が含まれてしまっていると、情報取扱い上顧客がそのログを開発会社に出せなくなって作業に支障が生じる可能性があるので、そういう情報は極力ログなどに出ないようにしたい」「セキュリティ上重大な情報でないとしても、個人の特定につながるような情報が含まれてしまうと取り扱い注意になってしまいますよね」「顧客の正社員しか扱えなくなったりとかですね」
🔗 Logger.logger_outputs_to?
にファイル名の文字列やFile
オブジェクトを渡せるようになった。
Logger.logger_outputs_to?
の出力先でファイル名もサポートするようになった。Logger.logger_outputs_to?('/var/log/rails.log')
Christian Schmidt
同Changelogより
Logger.logger_outputs_to?
でサポートしている出力先はSTDOUT
とSTDERR
のみで、File
オブジェクトやファイル名の文字列がサポートされていなかった。
同PRより
つっつきボイス:「今までは標準出力と標準エラーしか指定できなかったのをファイルパスでも渡せるようにしたというシンプルな修正ですね」
# activesupport/lib/active_support/logger.rb#L20
def self.logger_outputs_to?(logger, *sources)
loggers = if logger.is_a?(BroadcastLogger)
logger.broadcasts
else
[logger]
end
logdevs = loggers.map { |logger| logger.instance_variable_get(:@logdev) }
- logger_sources = logdevs.filter_map { |logdev| logdev.dev if logdev.respond_to?(:dev) }
+ logger_sources = logdevs.filter_map { |logdev| logdev.try(:filename) || logdev.try(:dev) }
- sources.intersect?(logger_sources)
+ normalize_sources(sources).intersect?(normalize_sources(logger_sources))
end
...
+ private
+ def self.normalize_sources(sources)
+ sources.map do |source|
+ source = source.path if source.respond_to?(:path)
+ source = File.realpath(source) if source.is_a?(String) && File.exist?(source)
+ source
+ end
+ end
end
参考: Rails API logger_outputs_to?
-- ActiveSupport::Logger
🔗 method_missing
の引数を...
などに置き換えた
キーワード引数が分離されて以来、
...
記法の方がシンプルかつより正しい。
同PRより
つっつきボイス:「これと次のプルリクは永和システムマネジメントさんが主催している"Rails / OSS パッチ会オンライン"↓のDiscordでたまたま見かけたもので、これはbyrootさんによるリファクタリングです」
参考: Rails / OSS パッチ会オンライン 2024年2月のお知らせ - ESM アジャイル事業部 開発者ブログ
「従来のmethod_missing
の引数がごっそり新しい...
記法などで置き換わってる」「文字通りRubyの書き方を現代化してますね」
# actionpack/lib/action_dispatch/http/mime_type.rb#L329
- def method_missing(method, *args)
+ def method_missing(method, ...)
if method.end_with?("?")
method[0..-2].downcase.to_sym == to_sym
else
super
end
end
# actionpack/lib/action_dispatch/system_test_case.rb#L181
- def method_missing(name, *args, &block)
+ def method_missing(name, ...)
if url_helpers.respond_to?(name)
- url_helpers.public_send(name, *args, &block)
+ url_helpers.public_send(name, ...)
else
super
end
end
「*args, **options, &block
みたいな長い引数も...
で置き換わってる↓」「新人向けに説明すると、*
が付いた仮引数はordered arguments(値のみの引数で、順序がある)をリストとして受け取る、**
が付いた仮引数はnamed arguments(名前つき引数、順序は入れ替え可能)をHashとして受け取る、&
が付いた仮引数は呼び出し時に渡されたブロックをProcとして受け取る、という昔からある書き方ですね」「書くときはその順序で書かなければいけないヤツ」
# actionview/lib/action_view/helpers/tag_helper.rb#L337
- def method_missing(called, *args, **options, &block)
- name = called.to_s.dasherize
+ def method_missing(called, ...)
+ name = called.name.dasherize
TagHelper.ensure_valid_html5_tag_name(name)
- tag_string(name, *args, **options, &block)
+ tag_string(name, ...)
end
end
「...
はRuby 2.7で入った新構文で、仮引数で受け取ったものをそのままforwardする記法でしたね」
「その後Ruby 3.0で(name, ...)
みたいに残りの引数をまとめてforwardすることも可能になってましたね↓」
「...
記法にすれば、受け取ったものを中継するだけのメソッドで引数の名前を考えずに済むのがとっても嬉しい」「しかも...
にすれば"全部受け取って丸投げするだけだよ"という意図も示せますよね」「...
は変数名に使えない文字だから中に何かがあっても参照しようがない😆」「たしかに😆」
「以前だとargs
とかarguments
とかoption
とかopts
のような引数名ってライブラリやプロジェクトごとにバラつきがちでしたよね」「そうなんですよ...」「プログラミングで最も時間がかかるのは名前を考えることだとよく言われるくらいなので、命名を減らせるのはとてもありがたい👍」
🔗 文字列をTime
やDateTime
に型変換したときのタイムゾーンオフセットのバグを修正
文字列を
Time
やDateTime
に型変換するときにタイムゾーンオフセットの分(minute)の値がマイナスだと正しく計算されないバグを修正。Akira Matsuda
同Changelogより
このパッチは、Active Modelの
Time
型キャスターが、指定の文字列内にあるマイナスのオフセットを正しく扱っていないバグを修正する。背景/詳細
指定した文字列内のタイムゾーンにマイナスのオフセットがある場合は時(hour)と分(minute)の値を両方とも正負反転する必要があるが、現在のコードではhourだけが正負反転されている。
たとえば
Newfoundland Time Zone (UTC-03:30)
の場合、オフセット部分は"-03:30"
となり、これは「-3
時間と-30
分」として扱わなければならないが、これまでは「-3
時間と+30
分」として算出されていたため、実際の時刻より1時間進んだ値を返していた。追加情報
Time
自身を解析するのは専門家でないと難しすぎる。このバグは、自分が#46868で提案しているRuby組み込みのTimeパーサーへの差し替えの理由付けになるだろう。また、このバグはTime
のプロである@nobuによって#19293(コメント)で発見および報告された(感謝!)。
同PRより
つっつきボイス:「nobuさんが見つけて報告したタイムゾーンのオフセットのバグをa_matsudaさんが修正したプルリクです」「"-03:30"
は-3
時間と-30
分が正しいのに分だけ誤って+30
分になってたのか!」「あ〜なるほど」「しかもオフセットがマイナスかつ30分の国でのみ起きるレアなバグ」
「TimeとかDateTimeの扱いはただでさえ難しくて気を遣うのに(ウォッチ20210713)、オフセットが1時間単位じゃなくて30分の国があるのってつらい」「時間表記は60進法と24進法が混じっていて表記は10進数だし、しかもゼロ始まりだし」「プルリクにも書かれているように専門家じゃないと難しいですよね」「奇しくも今日は閏年で2/29なので(つっつきの日)、この日しか起きないバグが起きたりしているようですね」
「ちなみにプルリクにあったAMoって何だろうと思ったらActive Modelのことでした」「ARならActive RecordしかないけどAMだけだとAction MailerやAction Mailboxもあって一意に定まらないからでしょうね」
後で調べると、30分ずれの国に加えて45分ずれの国もありました↓。
参考: Half Hour and 45-Minute Time Zones
🔗Rails
🔗 Sidekiqが動くしくみ(Ruby Weeklyより)
つっつきボイス:「Railsで非同期ジョブ処理によく使われるSidekiqの基本的なしくみを詳しく解説している記事です」「ちょっと長いけど、Sidekiqについて学びたい人は頑張って読んでみるといいと思います👍」
「最近はSolid Queue↑がRailsのデフォルトジョブエンジンに取り入れられることになったけど、Sidekiqとかが使われなくなるとは思えないですね」「SidekiqやRedisなど実績のあるものは今後も使い続けられると思います: BPS社内でbabaさんたちと話したときにも話題にしたんですが、Solid QueueはRDBにジョブエンジンの責務も負わせることになり、特にエンタープライズ系のアプリや多数のジョブをさばくようなアプリではRDBの仕事をあまり増やしたくないので、SidekiqやRedisなどは今後も普通に使っていくでしょうね」
🔗 Turbo 8のモーフィングを深堀りする(Ruby Weeklyより)
- 元記事: Turbo 8 morphing deep dive - how does it work? | Radan Skorić's personal site
- 元記事: Turbo 8 morphing deep dive - how idiomorph works? (with an interactive playground) | Radan Skorić's personal site
つっつきボイス:「先ごろリリースされたTurbo 8の2本立て記事で、2本目の記事の下には、Turbo 8で使われているidiomorphを動かせるplaygroundが付いていました」
🔗 testcontainers.com: テスト向けのDockerコンテナ実行環境をコードから起動して操作可能にする
- サイト: testcontainers.com
メジャーどころはだいたい提供されているのでtestcontainersは偉大。マイナーなアレとかアレが提供されていると嬉しいんだけど、主要RDBMSがあるだけでも開発が捗るhttps://t.co/wLy2z5SoPM
— カントク (@uokada) February 22, 2024
つっつきボイス:「このTestcontainersというサービスがRubyにも対応しているので取り上げてみました」「docker composeではcompose.yamlですべての環境をセットアップしなければならないけど、Testcontainersを使うとコンテナの起動後にもコードからプログラマブルに操作できるというものらしい: 何となくだけど、Railsのテストというよりは主に単一の実行ファイル形式のテストから使い捨てコンテナを利用したい人向けなのかも?」
「単に使い捨てのコンテナがコード内から起動して利用できるだけなら特に必要は感じないけど、起動後にプログラムからコンテナ内の設定をテストごとにある程度操作したりできるんだとしたらちょっといいかも」「PostgreSQLやMySQLやRedisやSeleniumなどのコンテナが用意されているんですね」「Seleniumはなくてもいいけど、RabbitMQやRedisのような複雑なサービスを本番同様にテスト環境でコードの中から動的に使い捨てることができるんなら使ってみたいかも」
# 同リポジトリより
container = Testcontainers::DockerContainer.new("redis:6.2-alpine").with_exposed_port(6379)
container.start
host = container.host
port = container.mapped_port(6379)
「Testcontainersサイトにあるこの記事が参考になりそうですね↓」「ありがとうございます🙏」
参考: What is Testcontainers, and why should you use it?
Testcontainersで解決される問題:
- 事前にプロビジョニングされた統合テストインフラを用意する必要がない。
Testcontainers APIはテストの実行前に必要なサービスを提供し、インフラを定義するコードを実際のテストコードのすぐ近くに書ける。各パイプラインは分離されたサービスのセットで実行されるため、複数のビルドパイプラインがパラレル実行される場合でもデータ競合の問題は発生しない。
単体テストを実行するのと同じように、統合テストをIDEから直接実行可能になる。
変更のプッシュや、CI統合テストの実行完了を待つ必要がない。テストの実行後、Testcontainers はコンテナを自動的にクリーンアップする。
同記事より
🔗 その他Rails
- 元記事: Ruby on Rails — Rails Foundation and Doximity to Sponsor Rails Girls São Paulo 2024(Rails公式ニュースより)
つっつきボイス:「The Rails FoundationとDoximityがブラジルのサンパウロで活動しているRails Girls 2024のスポンサーになったという記事です」「う、ポルトガル語わからん」
「Rails Girlsって日本の団体しか知らなかったんですが、他の国にもあるんですね」「フィンランドのヘルシンキで最初に設立されたRails Girls以外にもいくつかの国でも活動していて、日本のRails Girlsもほぼ同じぐらい歴史がありますよ」「そうなんですね」
参考: Rails Girls -- ヘルシンキ
参考: Rails Girls - Japanese
🔗Ruby
🔗 JRubyのPrismが登場(Ruby Weeklyより)
参考: Prism pluggable integration work by enebo · Pull Request #8103 · jruby/jruby
つっつきボイス:「少し前にRubyの新パーサーであるPrismのJRuby版がリリースされたそうです」「お〜すごい!」「今でこそJRubyはRuby 3.1互換ですけど、以前はRubyのバージョンアップになかなか追いつけなくて苦労していましたよね(ウォッチ20221207)」「以前は移植のためにJRubyで独自パーサーをメンテしていたけど、Prismの目標のひとつがJRubyを支援することだったはずでしたね」
参考: Home — JRuby.org
今回は以上です。
バックナンバー(2024年度第1四半期)
週刊Railsウォッチ: Rails 8でSprocketsがPropshaftに置き換わる、devcontainerサポートほか(20240228)
- 20240227後編 Turbo Nativeアプリ、書籍『Everyday Rails Testing with RSpec』新版執筆開始ほか
- 20240221前編 form_withのmodelオプションへのnil渡しが非推奨化、Dockerfileでjemallocが有効にほか
- 20240207後編 aws-sdk-rubyの全gemにRBSファイルが追加ほか
- 20240206前編 Pumaのデフォルトスレッド数変更、Rails 1.0をRuby 3.3で動かすほか
- 20240125後編 RailsコントローラのparamsはHashではない、ruby-enumほか
- 20240123前編 Railsの必須Rubyバージョンが3.1.0以上に変更ほか
- 20240119後編 Ruby 3.3でYJITを有効にすべき理由、Turbo 8の注意点8つほか
- 20240117前編 Rails 8マイルストーン、2023年のRails振り返り、Solid Queueほか
ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSやruby-jp SlackやRedditなど)です。
週刊Railsウォッチについて
TechRachoではRubyやRailsなどの最新情報記事を平日に公開しています。TechRacho記事をいち早くお読みになりたい方はTwitterにて@techrachoのフォローをお願いします。また、タグやカテゴリごとにRSSフィードを購読することもできます(例:週刊Railsウォッチタグ)