- 2025/10/22にRails8.1がリリースされましたね
- Ruby on Rails 8.1 Release Notes — Ruby on Rails Guidesにリリースノートが書かれている
- 上記メジャーフィーチャーに含まれなかったマイナーフィーチャーのうち、気になったものをざっくりまとめています
- 間違いの指摘や、これも追加してくれ〜という物があればコメントお願いします
- allow path regexp in SilenceRequest middleware by rainerborene · Pull Request #53561 · rails/rails · GitHub
- Silence healthcheck requests from the log by dhh · Pull Request #52789 · rails/rails · GitHub で
/upにきたリクエストについてはログに残さないようになった/upの部分は設定で変更可能なんだけど、文字列で受け付けるため単一のパスしか対象にできなかった
- 今回のPRで正規表現も受け付けるようになったので、柔軟に複数のパスを受け付けるようになった
- この手のやつ、みんな自前でやりがちだったけどRails公式でできるようになって便利じゃないですかね
- 開発環境だとリロードが走る
- テスト環境だとメソッドの再定義(例: モック)が実行される
- のでYJITをオンにしても速くならないでしょ、とのことで開発環境とテスト環境ではYJITはオフになった(
config.load_defaults 8.1とした場合) - Don't enable YJIT in development and test environments · rails/rails@76e2b7e · GitHub
- ↑のコミット作った人はYJITをオフにして30%速度が向上したとのこと
- Add
application-namemetadata to application layout by stevepolitodesign · Pull Request #54257 · rails/rails - metaタグにapplication-nameというのがあってそれがrails newしたときのlayout/application.htmlに追加されました
- 標準メタデータ名 - HTML: ハイパーテキストマークアップ言語 | MDN
- PWAなどのアプリケーション名として使われるらしい
- Support hash options for YJIT configuration by a5-stable · Pull Request #54662 · rails/rails
- Ruby 3.4から、RubyVM::YJIT.enableに対してオプションでYJITの設定を渡せるようになった
- logとstats
- 3.5からはmem-sizeとcall-thresholdも渡せるようになる模様
- Allow YJIT
mem-sizeandcall-thresholdto be set at runtime viaYJIT.enable()by annichai-stripe · Pull Request #12505 · ruby/ruby
- 「Railsを起動したあとにYJITを有効にする」(つまりRubyVM::YJIT.enableを使う)だとデフォルト設定を変更することができなかったので、便利な変更なんじゃないでしょうか
- Stop generating bundler binstub: by Edouard-chin · Pull Request #54687 · rails/rails
- bundler側でbin/bundleやめるという話になったのでrails newしてもbin/bundleを生成しないようになった
- 最近のbundlerはGemfile.lockに書いてあるバージョンのbundlerがインストールされていなければ自動でインストールして切り替えるようになっている
- bin/bundleだと↑の仕組みが動かなかったり、動くバージョンが厳密でない(~> x.y)だったりする模様
- みんなbin/bundle使ってないと思うのでそんなに影響はなさそうではある
- Add a default bin/bundle-audit configuration by dhh · Pull Request #54695 · rails/rails
- DHH作のPR
- rubysec/bundler-audit: Patch-level verification for Bundler はGemfile.lockをみて脆弱性のあるバージョンがあったら教えてくれるもの
- これがrails newしたときのデフォルトのGemfileにはいった
- さらにrails newしたときにできるデフォルトのGitHub Actionsでも実行するようになった
- ここで議論が起きている
- 脆弱性を解消したgemがリリースされていないときにCIがずっと赤くなり、しかも解消できないのでCIにいれるのは反対派 (byroot)
- 解消できないのがわかってるなら無視リストにいれるか、赤くても無視してマージしたらいいじゃん派 (dhh)
- 議論自体は解決してないが、PR作ったのはdhhなのですっとマージされた
- CIに対するスタンスの差が出た感
- DHHはOne Person FrameworkとしてRailsを扱っているんだろうな、という感想を持ちました
- Disable bootsnap parallel precompilation to workaround QEMU bug by viktorianer · Pull Request #55636 · rails/rails
- どうやらbootsnapのprecompileを並列実行するのと相性が悪い(デッドロックすることがある)らしい
- precompileをやめてハングしないようにする修正が入った
- kamalでデプロイするひとは踏むかもしれません
- Add
ActiveSupport::Testing::NotificationAssertionstest helper module by larouxn · Pull Request #53065 · rails/rails · GitHub - ActiveSupport::Notificationsを使っている人には便利そう
assert_notification("post.submitted", title: "Cool Post") do
post.submit(title: "Cool Post") # => emits matching notification
end
assert_notifications_count("post.submitted", 1) do
post.submit(title: "Cool Post") # => emits matching notification
end
assert_no_notifications("post.submitted") do
post.destroy # => emits non-matching notification
end
notifications = capture_notifications("post.submitted") do
post.submit(title: "Cool Post") # => emits matching notification
end- Support symbol proc on callback conditional by Roriz · Pull Request #54064 · rails/rails · GitHub
- 次のように、
unless(とif)にlambda(&:method_name)が渡せるようになった- これまではArgumentErrorになっていた
before_save Proc.new { |r| r.history << "b00m" }, unless: lambda(&:history)- Introduce ActiveSupport::ErrorReport#add_middleware by andrewn617 · Pull Request #54512 · rails/rails
- Use
#reportparameters in error context middleware by dersam · Pull Request #54642 · rails/rails - Sentryなどのエラー管理系サービスにエラー情報を送るとき、コンテキストとしてアプリケーション独自の情報を送ることができる
- それをErrorReporterでもできるようにした、というのがこのPR
Rails.error.add_middleware(-> (error, context) { context.merge({ foo: :bar }) })- add_middlewareという名前からわかるように、rack middlewareのように複数のlambdaを渡すことができる
- Add
Cache#read_counterandCache#write_counterby ghiculescu · Pull Request #54855 · rails/rails ActiveSupport::Cacheにはもともとincrementメソッドがあり、キャッシュをカウンターとして使うことができる- しかしカウンターの値を読み込む/書き込むときにはwrite/readメソッドに
raw: trueをオプションをつけないといけなかった- キャッシュはmessagepackやmarshalやjsonでシリアライズされて格納されるので、例えばmessagepackで1をdumpすると"\x01"になりこれだとincrementできない
- カウンター用の専用メソッドとしてread_counter, write_counterができた
- 実際は
raw: trueをつけつつread/writeしているだけ
- 実際は
- Always fully clear current attributes by byroot · Pull Request #55139 · rails/rails
- CurrentAttributesはリクエストごとに毎回
attributeで設定した属性をreset(初期値に戻す)をする - が、CurrentAttributesのインスタンス自体は使い回すので、独自でインスタンス変数などを定義しているとリクエストをまたいで状態が残ってしまう
- そういう使い方をしているのがよくないんだけど、そういう使い方をしても問題ないように毎回インスタンスを作り直すように変わりました
- Stop escaping JS separators in JSON by default by etiennebarrie · Pull Request #55800 · rails/rails
- 昔はvalidな文字ではなかったのだけど今はそうではない(validな文字列である)とのことでエスケープする必要がなくなったとのこと
- 昔はJSエンジンが文字列中に2028や2029を見つけるとエラーになっていたが、今は普通に文字として扱われる
- JSONパーサーは昔から2028や2029を扱えたのでこの差異をなくす、というのが2019年頃に行われたらしい
- 非互換な変更なので設定で切り替えられるようになっている
- ↓もしくは
config.load_defaults 8.1で有効になる
config.active_support.escape_js_separators_in_json = false- Migrate
ActiveRecord::Normalizationto Active Model by seanpdoyle · Pull Request #53887 · rails/rails - もともとActive Recordのメソッドとして追加されたけど、ActiveModelでも使いたいし、移行できるとのことでコードが移動された
- Add
except_on:option for validation callbacks by bensheldon · Pull Request #54665 · rails/rails - 8.0以降、validatesの条件としてexcept_onが使えるようになっている
- Add
:except_onoption for validations by DRBragg · Pull Request #43495 · rails/rails - 一貫性のために before_validationとafter_validationでもexcept_onがほしいということで入った
- Add
- Make reset token expiry configurable in has_secure_password by jevin · Pull Request #55574 · rails/rails
- もともと
has_secure_passwordで作ったpassword_reset_tokenメソッドは有効期限が15分決め打ちだったのを↓のように可変にできるようになった。 has_secure_password reset_token: { expires_in: 1.hour }
- Allow to tag serialized attributes as comparable by byroot · Pull Request #53946 · rails/rails
- ARにserializeというメソッドがあり、例えばtext型のDBカラムにYAMLやJSONを突っ込むことができる
- 変更があったときにUPDATEする
- これまで「変更があった」はシリアライズしたYAMLやJSONなどを比較して変更があればUPDATEしていた
- するとYAMLやJSONライブラリの仕様変更があると、別のカラムを更新するときにシリアライズなカラムも強制的にUPDATEの対象になってしまう
- これがおそらくshopifyで問題になった
- libyamlの実装が変更されて、末尾のスペースがなくなった
- 結果として不要にUPDATEが実行された
- 次のように
comparable: trueをオプションとして渡すとデシリアライズされているオブジェクト同士の比較をして、差分がなければUPDATEしない、となりこの問題を回避できる
serialize :config, type: Hash, coder: JSON, comparable: true- Sort table columns by name when dumping schema by jduff · Pull Request #53281 · rails/rails · GitHub
- これまではカラムが作られた順番でソートされていたため、環境によって順番がズレて次のような差分ができていた
t.string "county"
- t.string "country_code"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
+ t.string "country_code"
t.string "urn"- 今後はアルファベット順になるので↑のような差分がなくなって良い
- カラムの定義順が大事なんだよ!という人はstructure.sqlを使ってくれという方針の模様
- Introduce versions formatter for the schema dumper by fatkodima · Pull Request #53797 · rails/rails · GitHub
- structure.sqlを利用しているとschema_migrations(適用したmigrationバージョンを管理しているテーブル)はバージョンの降順になる
- つまり新しいmigration AとBを別々に適用すると、structure.sqlの同じ行が更新される
- なので大きいチームで開発しているとstructure.sql起因のコンフリクトがよく起きていた
- これを解消するために、バージョンをどのように挿入するかカスタマイズできるようになった
- 例えばバージョンのハッシュ値順にする、などするとバラバラにバージョンが入るのでコンフリクトの確率は下がる
- デフォルトはこれまでと同様バージョン番号の降順
- Fix boolean columns triggering MySQL deprecation by skipkayhil · Pull Request #54144 · rails/rails
- MySQLのbooleanは
tinyint(1)だった - これは
tinyint(-128~127)型で、表示幅が1桁ということを意味する(1)は表示幅を表すだけで、格納方式には影響していない- のだけど1桁を表すのかな、と勘違いされやすいので廃止の方向
tinyint(1)のような書き方をするとwarningがでるshow create tablesの出力結果にも表示されなくなるtinyint(1)だけはbooleanとして使われているので例外的に表示されるらしい
- なのでRailsでは
tinyint(1)はやめてboolean(これはtinyint(1)のエイリアス)を使うようになった
- JSON serialized attributes can return symbolized keys by matthaigh27 · Pull Request #54172 · rails/rails
- serializeでよく使うのはJSON
- JSONは知っての通りデフォルトでパースすると
{ "hoge" => "fuga"}のようにキーは文字列になってしまう - 毎回deep_symbolize_keysするのは面倒
serialize :config, coder: ActiveRecord::Coder::JSON.new(symbolize_names: true)- それを解決するために、↑のように
symbolize_names: trueをオプションとして渡したActiveRecord::Coder::JSONオブジェクトをcoderオプションに渡すことを可能にしたのがこのPR
- Add support for index visibility for MySQL v8.0.0+ and MariaDB v10.6.0+ by mtaner · Pull Request #54332 · rails/rails
- MySQL8.0.0以上とMariaDB10.6.0以上では「クエリオプティマイザからはそのインデックスを使わない」というインデックスを指定できる
- インデックスは削除されているわけではなくてちゃんと更新される
- インデックスを削除/追加する前に一回無効な状態にして様子を見る、ができて便利そう
- PostgreSQLではまだこれと同等の機能は入っていない
- activerecord: Don't always append primary keys etc. to order conditions by issyl0 · Pull Request #54679 · rails/rails
- implicit_order_columnという設定がActiveRecordにある
- これは、例えば
firstとかlastを実行したときに使われるソート用のカラム - なにも設定されていなかったらprimary keyが使われる
- でも例えばUUIDをprimary keyにしていたら…?
firstやlastでなにが返ってくるかよくわからないですよね
- そういうときに
implicit_order_columnを設定する - 仮に"author_name"みたいなのをimplicit_order_columnを設定したとき、
ORDER BY author_name ASC, id ASCのようにprimary keyが2つ目のorder用カラムとして指定される仕様になっていた- author_nameがユニークじゃないときでも一意なレコードを返せるようにする目的
- でもauthor_nameがユニークだったらidの指定は不要ですよね
- というわけで次のように配列の最後にnilをいれることでidの指定を外せるようになった
self.implicit_order_column = ["author_name", nil]- Optimize Active Record batching further when using ranges by maximerety · Pull Request #51243 · rails/rails
find_eachなどのメソッドが依存しているin_batchesというメソッドがある- find_eachなどが使うrelationを返すやつ
- 関連だけほしいときはこっちを使う
- in_batchesが返すrelationのデフォルトの振る舞いはこう(cursorでバッチに使うキーを設定しなかった場合)
- デフォルト1000件の主キーをpluckで取得する
- IN句で主キーを設定したリレーションを返す
- use_rangesというオプションが明示的に指定されているか、単に
User.in_batchesのようになんの条件も設定されていなかったときの振る舞いはこうだった- デフォルト1000件の主キーをpluckで取得する
- pluckで取得した主キーの最後の値を利用して
(id >= x AND id <= y)のようなクエリを発行するリレーションを作る
- use_rangesはIN句よりは速いけどpluckで1000件取得したやつの最後の値しか使わないのが無駄
- 最初の値は前回のイテレーションの結果もしくはstartオプションで明示的に指定しているのでわかっている
- そこでpluckの代わりに
offset 999 limit 1なクエリを使って最後の値だけを取るようにして高速化したのがこのPR- これでレコード数の多いテーブルのin_batchesがかなり高速化した
- 最後のイテレーションのときはoffset 999 limit 1だとうまく最後のレコードを取得することができないので追加で1クエリ必要になる、というのが欠点ではあるけど、トータルで見たらメリットが大きい
- [Fix #54591] Raise an error in order dependent finder methods when the model has no order columns by joshuay03 · Pull Request #54608 · rails/rails
- firstとかlastはorder byを利用する
- そのときに明示的な
orderがない、primary_keyがない、query_constraintsがないを満たすとorder byが使えない - 8.0の実装だとfirstはorder byなしでクエリが発行され、lastはエラーになる模様
- firstの結果が不定なのは良くない、ということで専用の例外を作ってエラーになるようにしたのがこのPR
- そのときに明示的な
- この設定は非互換なので8.1から設定↓でオンにする形で入り、8.2からデフォルトの振る舞いになる予定
config.active_record.raise_on_missing_required_finder_order_columns = true- 普通にRailsアプリケーションを作っていればprimary_keyがあるので関係ないけど、特殊なスキーマ構成にしていると踏むかもしれませんね
- Report json parse errors during json deserialization by Earlopain · Pull Request #55536 · rails/rails
- これまではパースに失敗しても何もせずにnilを返していた
- 重複したキーのJSONをパースするとき、json gemv2.13.0からwarning、v3からはエラーになる
- 気付けないの困るよね、ということで
ActiveSupport.error_reporter.report(e, source: "application.active_record")するようにした - JSONキー重複に関連する記事: Rails で JSON のキーが重複する場合にエラーを発生させる #Ruby - Qiita
-
Maintain AR connection pools in the background by matthewd · Pull Request #54175 · rails/rails
-
デフォルトの振る舞いは変わらない
-
poolがmax_connectionsにリネーム(poolはまだ使える)
-
つぎの設定が追加
- keepalive
- 指定した時間の間隔で接続になにか送ってまだ接続が生きているぞ、とサーバに示す
- デフォルト600秒(idle_timeoutが300秒なのでデフォルトでは使われない)
- max_age
- ここで指定した時間以上使われていたコネクションは回収される
- デフォルトはInfinity(回収しない)
- min_connections
- 常にDBに接続しておきたいコネクションの数
- 必要になったタイミングでコネクションを作る、だと時間がかかるので一定数事前に接続しておきたいという要望があるみたい
- keepalive
-
便利に使える機会はありそう
- Add
only_columnsto activerecord by Glyde02 · Pull Request #55121 · rails/rails - 複数のプロジェクトで同一のテーブルを扱っているときに便利、とのこと
- どういうケースで同一のテーブルを扱うことになるのかはわからない
- よくあることだ、と言っている人もいるけど本当かな
- Add
touchoption to#update_columnsand#update_columnmethods by moofkit · Pull Request #51455 · rails/rails - update_columnするときに一緒にupdated_atも更新したい、というユースケースを解決するために
touch: trueオプションを付与できるようになった - このユースケース自体はよくあるので便利だと思います
- update_allするときも
updated_atを更新しておいたほうがいいんだけど忘れがち
- update_allするときも
- Add
must-understanddirective by heka1024 · Pull Request #54833 · rails/rails - must-understandってなに?となるけどjxckさんのエントリを読むとわかる
- Cache-Control: must-understand ディレクティブとは何か | blog.jxck.io
- 新しく作られたステータスコードがキャッシュに関連する仕様だったときに、対応していないブラウザ側でキャッシュされることを防ぐためのもの
- 直近で使うことは多分ないので、こういうものがあることだけ覚えておけば良さそう
- Don't always escape JSON when calling
render json:by etiennebarrie · Pull Request #54643 · rails/rails - これまで
render json:でJSONを返すときは<>&U+2028U+2029などの特殊文字に対するエスケープが行われていた - jsやHTMLにJSONを埋め込むのであればエスケープは必要だけど、jsでfetchしてくるだけならエスケープは別にいらない
- Rails8.1のデフォルト設定ではエスケープしない、になった
- 非互換変更なので、8.1にアップグレードしたときに
config.load_defaults 8.1にするか、Rails.configuration.action_controller.escape_json_responses = falseと明示的に設定を有効にする必要がある - 上記設定にかかわらずrenderに
:callbackがついているときはエスケープされる(昔JSONPという仕組みがあってだな…)
- Add support for Cache-Control request directives by egg528 · Pull Request #55033 · rails/rails
- Cache-Control関連のメソッドはいくつかある
- でもRFC9111で定義されている全部はサポートしていない、とのことで全部サポートするようにメソッドがたくさん生やされた
# Boolean directives
request.cache_control_directives.only_if_cached? # => true/false
request.cache_control_directives.no_cache? # => true/false
request.cache_control_directives.no_store? # => true/false
request.cache_control_directives.no_transform? # => true/false
# Value directives
request.cache_control_directives.max_age # => integer or nil
request.cache_control_directives.max_stale # => integer or nil (or true for valueless max-stale)
request.cache_control_directives.min_fresh # => integer or nil
request.cache_control_directives.stale_if_error # => integer or nil
# Special helpers for max-stale
request.cache_control_directives.max_stale? # => true if max-stale present (with or without value)
request.cache_control_directives.max_stale_unlimited? # => true only for valueless max-stale- igorkasyanchuk/editor_opener: Open the source file with bug from the browser
- ↑はエラーページから該当するファイルをエディタで開けるようにするgem
- これをRails本体に入れたいぞ、というPRがたちマージされた
- Add support to open files in the source code editor from the crash page by igorkasyanchuk · Pull Request #55295 · rails/rails
- エラーページの行番号やスタックトレースにリンクがあり、クリックすると対応するエディタが開く
- べんり
- ちなみにBetterErrorsにも似たような機能があります
- Add Copy as Text button to error pages by mikker · Pull Request #55431 · rails/rails
- ↑に添付されている動画を見ると便利さがわかる
- エラーの内容をAIに聞くときにめちゃ便利につかえそう
- BetterErrorsキラーな機能の予感がします
- Fix errors when querystring keys have invalid enco ding by cmitz · Pull Request #55319 · rails/rails
- "%81E=bar"のような、キー部分がUTF8ではないクエリが飛んできたときにこれまでは4xxじゃなくて500が返ってきてしまっていたのを4xx(内部的には
ActionDispatch::InvalidParameterErrorをraiseさせている)にするようにした
- Return a 500 on MissingController errors by byroot · Pull Request #53964 · rails/rails
get "/people" => "does_not_exists#index"みたいなルーティングがあったときに/peopleにアクセスするとこれまでは404が返ってきていたんだけど500になった- これはなんと11年前からのIssueらしい
- これまでは
get ':controller(/:action(/:id))'みたいな書き方ができたせいで直すのが難しかったが、8.1から/:controllerみたいな書き方ができなくなるので対応ができた、という話らしい
- Allow hosts redirects from
hostsRails configuration by byroot · Pull Request #55420 · rails/rails - デフォルトのredirect_toは他のホストに遷移しようとするとエラーになる
allow_other_host: trueをつければ他のホストに遷移できるけど、どこでも遷移できてしまう- 自社で複数のドメインを扱っているときに「このドメインならリダイレクトOK」というリストがあると便利
- そこで
config.action_controller.allowed_redirect_hosts << "example.com"で指定できるようになった
- Merge pull request #55308 from Shopify/raise-on-relative-redirects-wi… · rails/rails@46d2afa
- 最近のredirect_toは
allow_other_host: trueをオプションとしてつけない限り他のドメインに遷移することはできない - OAuthなどの認証で
allow_other_host: trueをつけざるを得ない、というケースが有る - このときに相対URL形式で
/始まりじゃないものを受け付けると脆弱性につながるのでこれを禁止にする- 例えば
redirect_to "@attacker.com"とするhttp://[email protected]に遷移する @の前はユーザ名として扱われるので、相対URLとしてyourdomain.comに遷移するのを想定しているはずなのにattacker.comに遷移してしまう/始まりじゃない文字列がredirect_toに渡された時の振る舞いは3つ設定できる- log (何も設定していないときのデフォルト)
- notify
- raise(
config.load_defaults 8.1としたときのデフォルト)
- 例えば
- Allow custom domain extractor class on ActionDispatch::Http::URL by rainerborene · Pull Request #50763 · rails/rails
- これまで自社のドメインでどこまでがドメイン部分でどこからがサブドメイン部分なのかというのは config.action_dispatch.tld_lengthで固定値で判別していた
- ドメインが一つだけで固定されていればそれでよいのだけど、独自ドメイン設定可能なSaaSなどだと困る
- そこでドメインを判別する場所を差し替えられるような口を作った
- PR作者はそのうえで Public Suffix List を見て動的にドメインを判別させたいみたい
- Add render json to health by francesco-loreti · Pull Request #55092 · rails/rails
- 最近のRailsは
/upがhealthcheck用のパスとして用意されている - これまではHTML決め打ちで返していたけど、
/up.jsonだったりAcceptヘッダがapplication/jsonであればjson形式のレスポンスが返るようになった
- Rate Limiting: Allow to define shared rate limit across controllers. by arthurwozniak · Pull Request #53449 · rails/rails
- API全体に制限をかけるユースケースで、コントローラをまたいでアクセス回数をカウントしたいが、これまではコントローラ単位でしかカウントできなかった
- scopeというオプションが生えて、これが共通であれば同じキーを使ってキャッシュに回数を書き込むようになる
class APIController < ActionController::API
rate_limit to: 2, within: 2.seconds, scope: "api"
end
class API::PostsController < APIController
# ...
end
class API::UsersController < APIController
# ...
end- RateLimiting: raise
ActionController::TooManyRequestserror by seanpdoyle · Pull Request #55501 · rails/rails - 429をダイレクトに返すのではなくActionController::TooManyRequestsをraiseするようになった
- 例外クラスをはさんでrack middlewareでrescueして429を返すので基本的な振る舞いは変わらないけど、ActionController::BadRequest→400やActiveRecord::RecordNotFound→404などと同じように振る舞わせたいということみたい
- 自前でrescue_fromでなにか別の処理を挟むことができてべんり
- RateLimiting: support method names for
:byand:with· rails/rails@63166fe - これまで独自の振る舞いをさせたいときはlambdaだけが指定できたけれど、before_actionなどのようにシンボルを受け取り、シンボルが指すメソッドを実行する形式も使えるようになった
- Add
dom_targethelper to createdom_id-like strings from an unlimited number of objects by bensheldon · Pull Request #55204 · rails/rails dom_idだとモデルのidベースの文字列しか返せないので、モデルに関する文字列が複数欲しくなるような複雑なケースに対応できない、ということで追加された- 使い方は↓見ればわかるはず
dom_target(Post.find(45)) # => "post_45"
dom_target(Post.find(45), :edit) # => "post_45_edit"
dom_target(Post.find(45), :edit, :special) # => "post_45_edit_special"
dom_target(Post.find(45), Comment.find(1)) # => "post_45_comment_1"- Add
relative_time_in_wordshelper to ActionView by MatheusRich · Pull Request #55405 · rails/rails - time_ago_in_wordsというメソッドがそもそもあったけど、これは単に相対時間を返すだけだった
- 例: 3 minutes
- 3分後なのか3分前みたいな出し分けは自分でやる必要があった
- 後、前まで対応したメソッドが新設された
- 日本語もi18nの辞書を定義しておけば表示できる
- Allow
current_page?to match against specific HTTP method(s) with amethod:option by bensheldon · Pull Request #55286 · rails/rails - ビューヘルパーにcurrent_page?というメソッドがある
- 現在のページのタブをアクティブな表示にするときに使われる
- これは歴史的経緯でGETかHEADなリクエストにしか対応していなかった
- バリデーションエラーのときにそのままHTMLをレンダリングするとcurrent_page?がfalseを返して表示がおかしくなる、というのをなんとかしたい模様
- これを解決するためにmethodオプションを追加してそれ以外のメソッドでもOKにした
current_page?(controller: 'product', action: 'create', method: [:get, :post]) # => trueinput type="hidden"なタグに存在していたautocomplete="off"が削除される
- [Fix #55209] Remove autocomplete="off" from hidden inputs in button_to by nkulway · Pull Request #55336 · rails/rails
- firefoxのバグで、hiddenなinputタグの値に適当な値をautocompleteしてしまうというのがあった
- railsだとform中に
_method=patchみたいなhidden fieldタグをつけることがよくある - その値が急に変わってしまって想定していないリクエストになってしまうことがある
- railsだとform中に
- これの対応として、hiddenなタグには
autocomplete="off"を自動でつけるというコミットがRails7.0から入っていた - しかし今はそのバグは存在しないらしいので
autocomplete="off"を削除することになった - 非互換な変更なので
config.action_view.remove_hidden_field_autocomplete = trueもしくはconfig.load_defaults 8.1で有効になる
- Add
deliver_all_laterto enqueue multiple emails at once by fatkodima · Pull Request #55448 · rails/rails - perform_all_later のActionMailer版
- 内部ではperform_all_laterを利用している
- 一回にたくさんのメールを送信するような処理があるときに便利
- Add
report:option toActiveJob::Base#retry_onand#discard_onby andrewn617 · Pull Request #54541 · rails/rails - retry_onにreportオプションが追加された
- ActiveJobのretry_onはrescue_fromでエラーをrescueして一定時間後にまたジョブを実行する、という仕組みなのでナイーブな作りのエラー管理だとうまく通知がされない
report: trueであれば、ActiveSupport.error_reporter.report経由でエラー情報をエラー管理ツールなどに通知することができる- けど現状だと気をつけないと二重投稿になりそう
- Action Textが依存しているnpmであるtrixは、これまでAction Textに同梱されていたけど今回gemとして切り出された
- Drop vendored Trix files in favor of the
action_text-trixgem by flavorjones · Pull Request #55058 · rails/rails - trixにバグやセキュリティ修正があったときにRailsのバージョンを上げずに対応できるようにするため
- 37signals Dev — Introducing Action Push Native
- 過去にはAmazon SNSとPinpointを使っていたけどクラウドやめたので自前でpush通知用機能を作ったという流れらしい
- 最初はAction Native Pushという名前だったけど後にAction Push Naiveにリネームされた
- nativeという名前がついていることからもわかるように、iOSとAndroid向けのpush通知
- ブラウザ通知機能はない
- 37signals社製だけあってRailsと親和性のあるインタフェースを持っている印象
- 別途Action Push Webがリリース予定で、合わせてAction Pushとなる模様
- RailsWorldのDHHの発表でも言及されていた
- 37signals Dev — Lexxy: A new rich text editor for Rails
- これに合わせてActionTextで使うエディタもどこかのタイミングでLexxyに差し替わるはず
- trixでは実現していなかったmarkdown対応が入っている
- もともとRailsWorld2024のときにはActionTextでmarkdown使えるようにするという話があって、ONCE — Writebook ではサーバ側で実現していたけど結局エディタ側でやることにしたということみたい
- basecamp/lexxy
-
This is an early beta. It hasn't been battle-tested yet. Please try it out and report any issues you find.
- 現状↑とのことなのでActionTextの依存として入るとしたら8.2と思われます
- basecamp/activerecord-tenanted: Enable a Rails application to have separate sqlite database files for each tenant.
- マルチテナント系のgemは大まかに次の2つのアプローチ
- 単一DBを利用し、かつscopeやarelなどをゴニョゴニョして強制的に1つのテナント内のクエリになるようにする
- テナントごとにDBをわけて切り替えることで強制的に1つのテナント内のクエリになるようにする
- このgemは後者
- 現状、sqlite3のみをサポート
- 37signalsが作っている次のプロダクトで使うみたい
- SmartHR が定期メンテナンスを始めた理由とやめる理由 - SmartHR Tech Blog みたいなのがあるのでどれくらいのテナント数まで行けるのかが気になるところ
- sqlite3だとDB事に別ファイルになるので、MySQLやPostgreSQLよりも多くのテナントを抱えられるのかもしれないけどどうなんでしょうね
- sqlite3のレプリケーションのために独自のツールbeamerというのを作っている
- Rails World 2025 - Amsterdam, NL — SQLite Replication with Beamer で発表があったがコードは現状未公開
- kamal geo proxy(未公開)でマルチリージョンのルーティングをサポートするとのこと
- これで世界各地のユーザに対して一番近いリージョンのサーバからレスポンスを返す、というのを可能にするらしい