Home Software Libraries Ruby rails rails 7.1からrails 7.2への移行(アップデート、アップグレード)で必要な作業 @wakairo 2024/09/23 17:06 最終更新 2024/09/27 16:42 基本的にはRailsガイドの手順に従えば良いと思います。 ガイドの手順にもありますが、ぜひbin/rails app:updateコマンドを活用しましょう。 rails 7.2への移行で対応が必要そうな個別の作業について、以下のコメントでそれぞれ取り上げますので、ご参考になれば幸いです。
Home Software Libraries Ruby rails railsが挿入するfield_with_errorsの要素がBootstrapのinput-groupの表示を乱す問題 @wakairo 2024/09/18 20:23 最終更新 2024/09/18 20:25 問題の内容 フォームヘルパーで作成したフォームの標準の挙動として、 railsは、バリデーション・エラーが起きたフォーム要素を、field_with_errorsクラスを指定したdiv要素で囲みます。 つまり、バリデーション・エラーの有無によって、HTMLの階層構造が変わってしまいます。 その一方で、BootstrapのInput groupは、input-groupクラスを指定した要素の直接の子要素としてフォーム要素があることを前提としています。 そのためバリデーション・エラー時に、input-groupを指定した要素とフォーム要素の間にfield_with_errorsクラスのdiv要素が割り込むことで、Input groupの表示を乱してしまいます。 この問題に対し、インターネット上の情報では、 display: contents;を利用する方法や config.action_view.field_error_procの設定を変更する方法が紹介されていましたが、 私が試した限りでは問題の解決に至りませんでした。 そこで以下では、Input groupの利用を諦めて、Input groupに似た表示を他のBootstrapの機能で実現する方法をご紹介します。 なお、この問題に関して別の何か良い方法をご存じの方がいらっしゃいましたら、コメントをいただけると嬉しいです。 Bootstrapにおいて、Input groupに似た表示をgridで作成する方法 例として、Input groupを利用した以下のフォームの一部分を考えます。 <div class="input-group"> <span class="input-group-text">@</span> <%= f.text_field :username, class: 'form-control' %> </div> このフォームの一部分に近い表示を実現する例が以下のコードです。Input groupを利用した表示と比べると、「@」を囲む枠線は無くなりますが、文字やフォームの位置関係は近いものを実現できます。なお、ブラウザの画面幅をいろいろと変えた場合でも、位置関係の近さは大丈夫なはずです。 <div class="row gx-1"> <div class="col-auto col-form-label">@</div> <div class="col"> <%= f.text_field :username, class: 'form-control' %> </div> </div> このコードで利用しているBootstrapのクラスについて少し解説します。 まず横幅のバランスに関しては、以下のクラスを利用しています。 col-auto:内容の幅、つまり、上述のコードではフォームの左にある文字列である「@」の幅に基づいたカラムの幅になります。 col:残っている幅を均等に割り付けた幅になります。例えばcolクラスのカラムが2つあれば残りの幅が2分割されて均等に割り付けられます。上述のコードではcolクラスのカラムは1つですので、左にある「@」のカラムの幅を除いた残りの幅が全てこのtext_fieldのカラムに割り付けられます。 次に文字の位置(この例では「@」の位置)は、以下のクラスで調整しています col-form-label:指定することでフォームと上下位置をそろえられます。 gx-*:ガターを調整することで「@」とフォームの間の距離を調整し左右位置を調整しています。なお、左右位置を細かく調整したい場合にはmarginで直接細かく指定しても良いかもしれません。 (参考)Input groupに似せることよりもgridのカラム幅の指定を優先する場合 グリッドにおいて要素間の左右位置をそろえたいとき等では、col-autoを使わずに、以下のコードのようにカラム幅を指定する方法もあります。 このような場合では、文字列の左右位置の調整にtext-endクラスやtext-centerクラスが役立つかもしれません。 <div class="row gx-1"> <div class="col-2 col-form-label text-end">@</div> <div class="col-10"> <%= f.text_field :username, class: 'form-control' %> </div> </div> コードの動作確認をしたgemのバージョン rails (7.1.3.4) bootstrap (5.3.3)
Home Software Libraries Ruby rails Railsで複数のセッションを用いたintegration testを行う方法 @wakairo 2024/09/14 16:54 最終更新 2024/09/14 17:28 別々のブラウザから複数のユーザがログインするような状況を再現したintegration testを実装しようとするときなど、 ユーザごとにセッションが必要になるなどして、 1つのテスト内で複数のセッションが必要になることがあります。 Ruby on Railsのintegration testでは、 標準でこのような複数のセッションを用いるテストに対応しており、 公式ドキュメントの中では、ActionDispatch::IntegrationTestのAPIドキュメントに説明があります。 複数のセッションを用いたintegration testの例 公式情報は上述のAPIドキュメントをご覧いただければと思いますが、一応こちらでも簡単な例を使ってintegration testで複数のセッションを用いる方法をご紹介します。 ここではテスト内容として、ログインしているユーザが列挙されるページをテストすることを想定してテストコードを考えます。 具体的には、ユーザ1がログインするとこのページにユーザ1が現れ、 続けてユーザ2がログインすると今度はユーザ1とユーザ2の両方がページに現れることを確認します。 シンプルにopen_session()でセッションを作って用いる場合の例 複数のセッションを用いる場合に鍵となるメソッドは、open_session()です。 このメソッドはセッションのオブジェクト返しますので、必要なセッションの回数分呼び出せば、必要な数のセッションが作成出来ます。 セッションを複数作成したら、各セッションのオブジェクトのインスタンスメソッドとしてget()やassert_response()を呼び出すことで、 セッションを指定してアクションやアサーションを実行できます。 以下にサンプルコードを示します。 require "test_helper" class MultipleSessionTest < ActionDispatch::IntegrationTest test "login users page" do user1 = users(:one) user2 = users(:two) sess1 = open_session sess2 = open_session sess1.get login_path sess1.assert_response :success sess1.post login_path, params: { {email: user1.email, password: user1.password} } sess1.assert_response :found sess1.assert_redirected_to root_path sess1.follow_redirect! sess1.get login_users_path sess1.assert_response :success assert_match /@#{user1.username}/, sess1.response.body assert_no_match /@#{user2.username}/, sess1.response.body sess2.get login_path sess2.assert_response :success sess2.post login_path, params: { {email: user2.email, password: user2.password} } sess2.assert_response :found sess2.assert_redirected_to root_path sess2.follow_redirect! sess1.get login_users_path sess1.assert_response :success assert_match /@#{user1.username}/, sess1.response.body assert_match /@#{user2.username}/, sess1.response.body end end 繰り返される処理をDSLのメソッドにまとめる例 上述のシンプルな例を見てみると、ログイン処理などで、対象とするセッションは異なるものの、ほぼ同じ処理が繰り返されていることが分かります。 こういった繰り返される処理は、特定のテストで用いるセッションのDSL (Domain-Specific Language) としてまとめることが出来ます。 以下のテストコードは、テストの手順や内容は上述のシンプルな例と同じですが、今度はこのDSLを用いてコードの繰り返しを排除したものになっています。なお、テストコードの読みやすさの観点でも、こちらの例の方が良くなっているのではないでしょうか。 require "test_helper" class MultipleSessionWithDSLTest < ActionDispatch::IntegrationTest test "login users page" do user1 = users(:one) user2 = users(:two) sess1 = open_session_with_dsl sess2 = open_session_with_dsl sess1.login(user1) sess1.get_login_users assert_match /@#{user1.username}/, sess1.response.body assert_no_match /@#{user2.username}/, sess1.response.body sess2.login(user2) sess1.get_login_users assert_match /@#{user1.username}/, sess1.response.body assert_match /@#{user2.username}/, sess1.response.body end private module CustomDsl def login(user) get login_path assert_response :success post login_path, params: { {email: user.email, password: user.password} } assert_response :found assert_redirected_to root_path follow_redirect! end def get_login_users get login_users_path assert_response :success end end def open_session_with_dsl open_session do |sess| sess.extend(CustomDsl) end end end
Home Software Libraries Ruby rails Ruby on Railsのサポート終了日(各バージョンのEOL) @wakairo 2024/08/13 11:38 最終更新 2024/11/13 20:19 railsの各バージョンについて、セキュリティアップデートが行われる期限(End-of-Life)は以下の通りです。 8.0.x - 2026/11/07 7.2.x - 2026/08/09 7.1.x - 2025/10/01 7.0.x - 2025/04/01 6.1.xは、以下の通りサポートが終了しています。 6.1.x - 2024/10/1 なお、railsのサポート期間に関するより詳細な情報については本家のメンテナンス・ポリシーを参照してください。
Home Software Libraries Ruby meta-tags meta-tags側のtruncateでは、スペース文字のところで切り詰めが行われます @wakairo 2024/07/05 20:26 最終更新 2024/07/05 20:27 meta-tagsのv2.21.0で'truncate_on_natural_separator'の設定が追加されました。この設定を利用することで、スペース文字のところでの切り詰めを回避できるようになりました。このことを上のコメントに反映しました。
Home Software Libraries Ruby activerecord activerecordでは、firstを使った方が実装とSQLが揃って可読性が上がる Takuma @takuma_tech 2024/07/03 14:22 こちらの記事によると、activerecordでlastを使った場合、指定したorderを逆にして"LIMIT 1"とするSQLが発行されるそうです。 一方で、firstを使った場合、指定したorderはそのままで"LIMIT 1"とするSQLとなるので、railsのコードとSQLの対応関係が分かりやすくなります。 したがって、lastよりもfirstを使った方が実装とSQLが揃って可読性が上がるということがこの記事で主張されていました。 ご参考まで。
Home Software Libraries Ruby commonmarker commonmarker v1.xは、出力の編集が必要ならまだ時期尚早? @wakairo 2024/05/13 19:40 最終更新 2024/05/13 19:42 2023/12/25にcommonmarker v1.0.0がリリースされました。 それから4ヶ月以上が経過していますが、v1.xを採用せずにv0.xに留まっているライブラリやプロジェクトが多いように見受けられます。 たとえば、 jekyll-commonmarkのgem指定や commonmarker-rougeのgem指定は、 2024/05/13現在ではv0.xになっています。 v0.xで出来ていた編集操作がv1.xではまだ出来ない? commonmarkerにMarkdownを入力して、出力されたHTMLをそのまま使う分には現在のv1.xで十分でしょう。 しかし、スタイル変更やJavaScriptによる機能付与などで、出力されるHTMLを多少変更したいことがあります。 v0.xではこういうときに使えるものとして、任意のHTMLを挿入する方法があったのですが、少なくともこのv0.xの方法はv1.xでは出来なくなったようです。 Pluginの活用か何かで、v1.xでもv0.xと同じように、出力のHTMLを部分的に好き勝手な形に編集することは出来るのでしょうか? ご存じの方がいらっしゃいましたら、コメントをいただけると嬉しいです。
Home Software Libraries Ruby rails WSL2上にてrails serverで立ち上げたサーバに別デバイスからのアクセスを可能にする方法 @wakairo 2024/05/08 21:10 最終更新 2024/05/08 21:11 別デバイスからhttpsでrails serverにアクセスする方法 前述の方法で別デバイスからhttpでアクセスできるようになりますが、httpsでアクセスする必要がある場合には、 local-ssl-proxyを使ってhttpsをhttpに振り向けることで、httpsアクセスが可能になります。具体的な方法は以下をご覧ください。 なお別デバイスからhttpsでアクセスするには、前述のポートフォワーディングとファイアウォールの設定をhttpsのポート番号で行う必要があります。 local-ssl-proxyを使ってhttpsでhttp://localhost:3000/へアクセスする方法
Home Software Libraries JavaScript local-ssl-proxy local-ssl-proxyを使ってhttpsでhttp://localhost:3000/へアクセスする方法 @wakairo 2024/05/08 20:34 最終更新 2024/05/08 20:57 背景 Webの機能には、httpsでアクセスしているときにしか利用できないものがあります。 例えば、navigator.clipboardを用いてクリップボードへ書き込む機能はhttpsでアクセスしているときにのみ利用可能です。 ローカル環境においてhttpで走っている開発中のアプリに対して、こういった機能をテストするために、httpsでアクセスしたい場合があります。 ローカルでhttpsアクセスをhttpアクセスへ振り向ける方法 以下のコマンドを実行すれば、httpで走っている( http://localhost:3000/ )アプリに、ブラウザからhttps( https://localhost:3001/ )からアクセスできるようになります。 npx local-ssl-proxy --source 3001 --target 3000 なお、アプリが走っているPCとは別のデバイスからアクセスする場合には、httpのポートのために行ったポートフォワーディングやファイアウォールの設定がhttpsのポートにも必要となります。 (設定方法の参考資料) WSL2上にてrails serverで立ち上げたサーバに別デバイスからのアクセスを可能にする方法 余談その1 Copilot先生によれば、httpで走っているアプリにhttps相当でアクセスするための別の方法としては、以下のものがあるそうです。 localtunnelなど、ローカルで走っているアプリをインターネットに公開するサービスを利用してしまう。 Chrome DevToolsのリモートデバッグ機能を利用する。 なお、Copilot先生の回答全文はこちらです。 余談その2 local-ssl-proxyは、Copilot先生に教えてもらいました。Google検索ではlocal-ssl-proxyにはたどり着いていませんでした。
Home Software Libraries Ruby importmap-rails importmap-railsは、2.x系でiOS 16.3以前のサポートを打ち切りました。 @wakairo 2024/05/02 17:09 回避策が公式リポジトリのREADMEに掲載されたので、回避策のところを更新しました。
rails 7.1からrails 7.2への移行(アップデート、アップグレード)で必要な作業
基本的にはRailsガイドの手順に従えば良いと思います。
ガイドの手順にもありますが、ぜひ
bin/rails app:update
コマンドを活用しましょう。rails 7.2への移行で対応が必要そうな個別の作業について、以下のコメントでそれぞれ取り上げますので、ご参考になれば幸いです。
railsが挿入するfield_with_errorsの要素がBootstrapのinput-groupの表示を乱す問題
問題の内容
フォームヘルパーで作成したフォームの標準の挙動として、 railsは、バリデーション・エラーが起きたフォーム要素を、
field_with_errors
クラスを指定したdiv要素で囲みます。 つまり、バリデーション・エラーの有無によって、HTMLの階層構造が変わってしまいます。その一方で、BootstrapのInput groupは、
input-group
クラスを指定した要素の直接の子要素としてフォーム要素があることを前提としています。 そのためバリデーション・エラー時に、input-group
を指定した要素とフォーム要素の間にfield_with_errors
クラスのdiv要素が割り込むことで、Input groupの表示を乱してしまいます。この問題に対し、インターネット上の情報では、
display: contents;
を利用する方法やconfig.action_view.field_error_proc
の設定を変更する方法が紹介されていましたが、 私が試した限りでは問題の解決に至りませんでした。そこで以下では、Input groupの利用を諦めて、Input groupに似た表示を他のBootstrapの機能で実現する方法をご紹介します。
なお、この問題に関して別の何か良い方法をご存じの方がいらっしゃいましたら、コメントをいただけると嬉しいです。
Bootstrapにおいて、Input groupに似た表示をgridで作成する方法
例として、Input groupを利用した以下のフォームの一部分を考えます。
このフォームの一部分に近い表示を実現する例が以下のコードです。Input groupを利用した表示と比べると、「@」を囲む枠線は無くなりますが、文字やフォームの位置関係は近いものを実現できます。なお、ブラウザの画面幅をいろいろと変えた場合でも、位置関係の近さは大丈夫なはずです。
このコードで利用しているBootstrapのクラスについて少し解説します。
まず横幅のバランスに関しては、以下のクラスを利用しています。
col-auto
:内容の幅、つまり、上述のコードではフォームの左にある文字列である「@」の幅に基づいたカラムの幅になります。col
:残っている幅を均等に割り付けた幅になります。例えばcol
クラスのカラムが2つあれば残りの幅が2分割されて均等に割り付けられます。上述のコードではcol
クラスのカラムは1つですので、左にある「@」のカラムの幅を除いた残りの幅が全てこのtext_field
のカラムに割り付けられます。次に文字の位置(この例では「@」の位置)は、以下のクラスで調整しています
col-form-label
:指定することでフォームと上下位置をそろえられます。gx-*
:ガターを調整することで「@」とフォームの間の距離を調整し左右位置を調整しています。なお、左右位置を細かく調整したい場合にはmarginで直接細かく指定しても良いかもしれません。(参考)Input groupに似せることよりもgridのカラム幅の指定を優先する場合
グリッドにおいて要素間の左右位置をそろえたいとき等では、
col-auto
を使わずに、以下のコードのようにカラム幅を指定する方法もあります。 このような場合では、文字列の左右位置の調整にtext-end
クラスやtext-center
クラスが役立つかもしれません。コードの動作確認をしたgemのバージョン
Railsで複数のセッションを用いたintegration testを行う方法
別々のブラウザから複数のユーザがログインするような状況を再現したintegration testを実装しようとするときなど、 ユーザごとにセッションが必要になるなどして、 1つのテスト内で複数のセッションが必要になることがあります。
Ruby on Railsのintegration testでは、 標準でこのような複数のセッションを用いるテストに対応しており、 公式ドキュメントの中では、ActionDispatch::IntegrationTestのAPIドキュメントに説明があります。
複数のセッションを用いたintegration testの例
公式情報は上述のAPIドキュメントをご覧いただければと思いますが、一応こちらでも簡単な例を使ってintegration testで複数のセッションを用いる方法をご紹介します。
ここではテスト内容として、ログインしているユーザが列挙されるページをテストすることを想定してテストコードを考えます。 具体的には、ユーザ1がログインするとこのページにユーザ1が現れ、 続けてユーザ2がログインすると今度はユーザ1とユーザ2の両方がページに現れることを確認します。
シンプルにopen_session()でセッションを作って用いる場合の例
複数のセッションを用いる場合に鍵となるメソッドは、open_session()です。 このメソッドはセッションのオブジェクト返しますので、必要なセッションの回数分呼び出せば、必要な数のセッションが作成出来ます。 セッションを複数作成したら、各セッションのオブジェクトのインスタンスメソッドとしてget()やassert_response()を呼び出すことで、 セッションを指定してアクションやアサーションを実行できます。
以下にサンプルコードを示します。
繰り返される処理をDSLのメソッドにまとめる例
上述のシンプルな例を見てみると、ログイン処理などで、対象とするセッションは異なるものの、ほぼ同じ処理が繰り返されていることが分かります。 こういった繰り返される処理は、特定のテストで用いるセッションのDSL (Domain-Specific Language) としてまとめることが出来ます。
以下のテストコードは、テストの手順や内容は上述のシンプルな例と同じですが、今度はこのDSLを用いてコードの繰り返しを排除したものになっています。なお、テストコードの読みやすさの観点でも、こちらの例の方が良くなっているのではないでしょうか。
Ruby on Railsのサポート終了日(各バージョンのEOL)
railsの各バージョンについて、セキュリティアップデートが行われる期限(End-of-Life)は以下の通りです。
6.1.xは、以下の通りサポートが終了しています。
なお、railsのサポート期間に関するより詳細な情報については本家のメンテナンス・ポリシーを参照してください。
meta-tags側のtruncateでは、スペース文字のところで切り詰めが行われます
meta-tagsのv2.21.0で'truncate_on_natural_separator'の設定が追加されました。この設定を利用することで、スペース文字のところでの切り詰めを回避できるようになりました。このことを上のコメントに反映しました。
activerecordでは、firstを使った方が実装とSQLが揃って可読性が上がる
こちらの記事によると、activerecordでlastを使った場合、指定したorderを逆にして"LIMIT 1"とするSQLが発行されるそうです。
一方で、firstを使った場合、指定したorderはそのままで"LIMIT 1"とするSQLとなるので、railsのコードとSQLの対応関係が分かりやすくなります。
したがって、lastよりもfirstを使った方が実装とSQLが揃って可読性が上がるということがこの記事で主張されていました。 ご参考まで。
commonmarker v1.xは、出力の編集が必要ならまだ時期尚早?
2023/12/25にcommonmarker v1.0.0がリリースされました。 それから4ヶ月以上が経過していますが、v1.xを採用せずにv0.xに留まっているライブラリやプロジェクトが多いように見受けられます。
たとえば、 jekyll-commonmarkのgem指定や commonmarker-rougeのgem指定は、 2024/05/13現在ではv0.xになっています。
v0.xで出来ていた編集操作がv1.xではまだ出来ない?
commonmarkerにMarkdownを入力して、出力されたHTMLをそのまま使う分には現在のv1.xで十分でしょう。 しかし、スタイル変更やJavaScriptによる機能付与などで、出力されるHTMLを多少変更したいことがあります。 v0.xではこういうときに使えるものとして、任意のHTMLを挿入する方法があったのですが、少なくともこのv0.xの方法はv1.xでは出来なくなったようです。
Pluginの活用か何かで、v1.xでもv0.xと同じように、出力のHTMLを部分的に好き勝手な形に編集することは出来るのでしょうか? ご存じの方がいらっしゃいましたら、コメントをいただけると嬉しいです。
WSL2上にてrails serverで立ち上げたサーバに別デバイスからのアクセスを可能にする方法
別デバイスからhttpsで
rails server
にアクセスする方法前述の方法で別デバイスからhttpでアクセスできるようになりますが、httpsでアクセスする必要がある場合には、
local-ssl-proxy
を使ってhttpsをhttpに振り向けることで、httpsアクセスが可能になります。具体的な方法は以下をご覧ください。 なお別デバイスからhttpsでアクセスするには、前述のポートフォワーディングとファイアウォールの設定をhttpsのポート番号で行う必要があります。local-ssl-proxyを使ってhttpsでhttp://localhost:3000/へアクセスする方法
背景
Webの機能には、httpsでアクセスしているときにしか利用できないものがあります。 例えば、navigator.clipboardを用いてクリップボードへ書き込む機能はhttpsでアクセスしているときにのみ利用可能です。 ローカル環境においてhttpで走っている開発中のアプリに対して、こういった機能をテストするために、httpsでアクセスしたい場合があります。
ローカルでhttpsアクセスをhttpアクセスへ振り向ける方法
以下のコマンドを実行すれば、httpで走っている( http://localhost:3000/ )アプリに、ブラウザからhttps( https://localhost:3001/ )からアクセスできるようになります。
なお、アプリが走っているPCとは別のデバイスからアクセスする場合には、httpのポートのために行ったポートフォワーディングやファイアウォールの設定がhttpsのポートにも必要となります。
余談その1
Copilot先生によれば、httpで走っているアプリにhttps相当でアクセスするための別の方法としては、以下のものがあるそうです。
なお、Copilot先生の回答全文はこちらです。
余談その2
local-ssl-proxy
は、Copilot先生に教えてもらいました。Google検索ではlocal-ssl-proxy
にはたどり着いていませんでした。importmap-railsは、2.x系でiOS 16.3以前のサポートを打ち切りました。
回避策が公式リポジトリのREADMEに掲載されたので、回避策のところを更新しました。