Running 1 tests in a single process (parallelization threshold is 50)
Run options: --seed 32547
# Running:
/x/vendor/bundle/ruby/3.4.0/gems/railties-8.0.4/lib/rails/test_unit/line_filtering.rb:7:in 'run': wrong number of arguments (given 3, expected 1..2) (ArgumentError)
from /x/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.0/lib/minitest.rb:467:in 'block (2 levels) in Minitest::Runnable.run_suite'
from /x/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.0/lib/minitest.rb:463:in 'Array#each'
from /x/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.0/lib/minitest.rb:463:in 'block in Minitest::Runnable.run_suite'
from /x/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.0/lib/minitest.rb:505:in 'Minitest::Runnable.on_signal'
from /x/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.0/lib/minitest.rb:492:in 'Minitest::Runnable.with_info_handler'
from /x/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.0/lib/minitest.rb:462:in 'Minitest::Runnable.run_suite'
from /x/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.0/lib/minitest.rb:355:in 'block in Minitest.run_all_suites'
from /x/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.0/lib/minitest.rb:355:in 'Array#map'
from /x/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.0/lib/minitest.rb:355:in 'Minitest.run_all_suites'
from /x/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.0/lib/minitest.rb:310:in 'Minitest.run'
from /x/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.0/lib/minitest.rb:84:in 'block in Minitest.autorun'
Active Recordマイグレーションでのadd_foreign_keyとadd_referenceの違い
Railsガイドを一読しただけでは、 add_foreign_keyとadd_referenceが、それぞれどのようなもので、どう違うのかがいまいちよく分かりませんでした。 そこで、add_foreign_keyとadd_referenceによって
db/schema.rbがどのように変化するかを基に、 それぞれの機能について確認してみました。add_foreign_key
add_foreign_keyは外部キー制約の追加だけを行います。よって、カラムやインデックスの追加は行いません。
外部キー制約とは、子テーブルが参照している親のIDが親テーブルに存在することをデータベースレベルで保証する制約です。
例えば、以下の記述をマイグレーションファイルに行ったとします。
すると以下の記述が
db/schema.rbに追加されます。この記述は、products(子テーブル)のuser_idカラムに登場するIDが、users(親テーブル)のidカラムに必ず存在するように制約をかけています。
add_reference
add_referenceは、テーブル間の関連付けに関する複数の設定を一度に行える便利メソッドです。
add_referenceの基本機能は、カラムとインデックスの追加です。 例えば、以下の記述をマイグレーションファイルに行ったとします。
すると以下のように、users(親テーブル)に関連付ける2つの記述、具体的にはuser_idのカラムとインデックスをproducts(子テーブル)に追加する2つの記述が、
db/schema.rbに追加されます。またadd_referenceは、
foreign_key:trueオプションを追加することで、前述の2つに加えて外部キー制約も同時に設定できます。 例えば、以下の記述をマイグレーションファイルに行ったとします。すると以下のように、前述の2つの記述に加えて、add_foreign_keyの記述が
db/schema.rbに追加されます。(参考)add_referenceとt.referencesの機能は基本的に同じ
add_referenceとcreate_tableのブロックの中で呼び出すt.referencesは基本的に同じ機能を提供します(オプション以外の引数の部分で違いはありますが。) 実際にt.referencesへ渡せるオプションはadd_referenceと同じです。 また、t.referencesの実装とadd_referenceの実装のどちらも
ReferenceDefinition.newを内部で呼ぶ形になっています(v8.1.2で確認)。ActiveRecord::Rollbackで例外を伝播させずにロールバック後の処理を継続する
Active RecordのTransactionブロック内で例外が投げられた場合、ActiveRecord::Rollback以外の例外はロールバックの後に再度投げられます。
したがって、処理失敗で例外を投げるメソッド(
save!等)を使えば、基本的にその例外はロールバックの後Transactionブロックの外へ伝播します。 これをキャッチしなければ、RailsはHTTPのエラーレスポンスをブラウザ等のクライアントに返します。 つまり、「処理に失敗したら、ロールバックして、あとの処理は切り上げて、エラーレスポンスを返す」という挙動は簡単に実装できます。一方で、「ロールバック後に例外を出さずに処理を継続する」場合には、ActiveRecord::Rollbackを活用できます。 以下は、Transactionの成否でリダイレクト先を変えるコード例です。
minitest6にアップデートするとrails testがエラーになる
1/9にリリースされたRails v8.1.2は、minitest6で問題なさそうです。簡単にテストした分には、正常にテストが走りました。
ちなみにv8.1.1は、minitest6にすると、エラーにはならないものの、テストが全く拾われず
0 runs, 0 assertions, 0 failures, 0 errors, 0 skipsになっていました。minitest6にアップデートするとrails testがエラーになる
現象
2025/12/18にリリースされたminitest 6.0.0のgemにアップデートしたところ、
bin/rails testの実行で以下のエラーが発生して止まりました。ちなみに、テストが1つも無い状態ではこのエラーは発生しませんでした。とりあえずの回避策
Gemfileの
group :testのところに以下の記述を追加してminitestのバージョンを6よりも下に設定したところエラーは出なくなりました。SprocketsからPropshaftへの移行に関する注意点
Propshaftへ移行したらSprockets用の設定は削除可能
config/environments/production.rbにある以下の設定はSprocketsの設定なので、 Propshaftへ移行したら、削除可能です。参考情報
https://www.techtips.page/ja/comments/658
SprocketsからPropshaftへの移行に関する注意点
Propshaftは.erbを処理しない
Sprocketsは拡張子が
.erbのファイル(例:foo.scss.erb)を処理しますが、Propshaftは処理しません。 そのため、Sprockets で.erbを処理している場合、Propshaftへ移行するには次のいずれかの対応が必要になります。.erbの利用をやめ、プレーンなCSS/SCSSなどに書き換える.erbの処理を、Propshaftに渡す前の前処理として別途組み込むSprocketsからPropshaftへの移行に関する注意点
Propshaftへの移行に際して、tailwindcss-railsまたはdartsass-railsを選ぶのもあり
Propshaftの公式移行手順では、CSS関連の処理が必要な場合の選択肢として cssbundling-rails のみ紹介されていますが、 tailwindcss-rails と dartsass-rails という選択肢もあります。cssbundling-railsのREADMEには、選び方のヒントが掲載されています。
SprocketsからPropshaftへの移行に関する注意点
SprocketsからPropshaftへの移行手順は、 以下のPropshaftの公式手順で基本的には問題ないと思いますが、 この公式手順に記載されていないものを中心に、 移行における注意点をこのTopicで集約できればと思います。
https://github.com/rails/propshaft/blob/main/UPGRADING.md
OmniAuthを利用したログインのボタンやリンクではTurboをオフにした方が無難
OmniAuthを利用すると外部サービスの認証情報を用いたログインが可能となりますが、 そのログインのボタンやリンクでは、以下のように
data: {turbo: false}を付けてTurboをオフにしないと、ログインが機能しない場合があります。なお、公式のREADMEにあるRails向けサンプルでも
data: {turbo: false}が用いられています。また、Rails 7からは、Turboがデフォルト構成に組み込まれ有効になっているため、OmniAuthを利用する際は本件への注意が必要です。
`yield :foo`と`content_for :foo`の使い分け
動機
Rails 8.0.2でrails newをして生成されたapp/views/layouts/application.html.erbでは、 以下のように
yield :fooとcontent_for :fooが混在していました。content_forのAPIドキュメントによれば
yield :fooとcontent_for :fooの働きが等価となる場合もあるのですが、 このapplication.html.erbの例のように、片方に統一されず両方を利用しているケースがあったので、yield :fooとcontent_for :fooの使い分けについて調べる事にしました。結論
yield :fooを使う。ただし、以下の2つのケースではcontent_for :fooを使う。content_for :fooを使う。content_for :fooを使う。詳細
yieldはヘルパーメソッドの中では利用できない
content_forのAPIドキュメントに書かれている通り、 content_forは以下の例のようにヘルパーメソッド内で利用可能ですが、yieldは利用できません。
yieldとcontent_forでは、設定されていないときの戻り値が異なる
ビュー側で以下のように:fooに対して設定が行われていた場合、
yield :fooとcontent_for :fooの戻り値は、この例ではどちらも" Foo\n"であり、同じになります。しかし、ビュー側で前述のような記述がなく:fooに対して設定が行われていなかった場合、
yield :fooの戻り値が空文字列("")であるのに対し、content_for :fooの戻り値はnilであり、 戻り値が異なります。設定されていない場合に
content_for :fooがnilを戻す性質を利用することで、<title><%= content_for(:title) || "Sample" %></title>のような設定されているかどうかに応じて挙動を切り替えるコードを短く書くことができます。