Categories

Latest comments

rails 7.1からrails 7.2への移行(アップデート、アップグレード)で必要な作業

wakairo @wakairo
Last edited

rails 7.2におけるpublic_file_server.enabled

rails newで生成されるconfig/environments/test.rbにおいて、 7.1以前は以下の設定用コードが存在していましたが、 このプルリクエストのマージによって削除されました。

  config.public_file_server.enabled = true

削除された理由は、このプルリクエストによると、default値がtrue、かつ、全てのenvironment(test、development、production)の間で設定値に違いが無いということからです。 ですので、既存アプリにおいても、設定値をtrueとしている場合には、この設定用コードは削除してしまっても良いかもしれません。

0
Raw
https://www.techtips.page/en/comments/322

rails 7.1からrails 7.2への移行(アップデート、アップグレード)で必要な作業

wakairo @wakairo
Last edited

rails 7.2におけるannotate_rendered_view_with_filenames

annotate_rendered_view_with_filenamesは、rails 6.1で追加されたビューのテンプレートの開始と終了に対応するHTMLコメントを挿入する機能です。

rails newで生成されるconfig/environments/development.rbにおいて、 7.1以前はこの機能を有効化する以下のコードがコメントアウトされていましたが、 7.2からは以下のように有効になるコードになりました(この変更のPR)。 ちなみに、default値は7.1以前から変わらずfalseですので、 development.rb内の当該設定を意図的に変更しなければ、既存アプリの挙動が勝手に変わることはありません。

  config.action_view.annotate_rendered_view_with_filenames = true

確かにdevelopment環境において便利そうな機能ですので、7.2へのアップデートを機に、使い始めてみるのも良いかもしれません。

0
Raw
https://www.techtips.page/en/comments/321

rails 7.1からrails 7.2への移行(アップデート、アップグレード)で必要な作業

wakairo @wakairo
Last edited

基本的にはRailsガイドの手順に従えば良いと思います。

ガイドの手順にもありますが、ぜひbin/rails app:updateコマンドを活用しましょう。

rails 7.2への移行で対応が必要そうな個別の作業について、以下のコメントでそれぞれ取り上げますので、ご参考になれば幸いです。

0
Raw
https://www.techtips.page/en/comments/320
😄2
❤️2
🔧1

PostgreSQLイメージとPodmanを利用した使い捨てのコンテナ環境

wakairo @wakairo
Last edited

PostgreSQLに関した練習やテスト、実験などを行うときにPostgreSQLが動いている一時的な環境が欲しくなるときがあります。 PostgreSQLイメージとPodmanを利用すると、特定バージョンのPostgreSQLに関する一通りの操作ができる一時的なコンテナ環境を用意することが出来ます。

以下にコンテナ環境の作成、利用、削除の流れと方法を示します。

コンテナ環境の作成

以下の3つのコマンドを実行することで、PostgreSQLのコンテナ環境を作成し、クライアント側のコンテナのbash環境に入ることが出来ます。

なお、コマンド内の「16」のところはPostgreSQLのメジャーバージョンに相当しますので、ご利用になりたいバージョンの数に変更してください。 また、-v "$PWD":/x -w /xのオプションにより、ホストOSのカレントディレクトリにコンテナ内からもアクセス出来る状態でbashが立ち上がります。 したがって、実験などに利用したいファイルをカレントディレクトリに置いてから以下のコマンドを実行すればコンテナ内でもそのファイルを利用できますし、 コンテナ内で/xのディレクトリに作成したファイルはコンテナ環境を終了した後もホストOSのカレントディレクトリに残ります。

podman pod create --name tmp_pg
podman run --name tmp_pg-server --pod tmp_pg -e POSTGRES_PASSWORD=postgres -d postgres:16
podman run -it --rm -v "$PWD":/x -w /x --name tmp_pg-bash --pod tmp_pg postgres:16 bash

以下のようなプロンプトが表示されていれば成功です。クライアント側のコンテナのbash環境に入れました。

root@tmp_pg:/x#

クライアント側のコンテナのbash環境の利用

このbash環境では、psqlなどのPostgreSQLのコマンドを一通り利用することが出来ます。以下に例を示します。

PostgreSQLのターミナルを開く例:

psql -h localhost -U postgres -d postgres

バックアップファイルを作成する例:

pg_dump -Fc -h localhost -U postgres -d postgres -f backup.dump

バックアップファイルをリストアする例:

pg_restore --clean -h localhost -U postgres -d postgres backup.dump

クライアントのコンテナを終了しそのbash環境から退出する場合はexitコマンドで抜けられます。 また、退出後にもう一度クライアントを使いたくなった場合は、後述のコンテナ環境全体の削除をまだしていなければ、 以下の3つめのコマンドだけ実行すれば、クライアントのコンテナをもう一度作成しそのbash環境に入ることが出来ます。

podman run -it --rm -v "$PWD":/x -w /x --name tmp_pg-bash --pod tmp_pg postgres:16 bash

コンテナ環境全体の削除

以下のコマンドで、コンテナ環境全体の停止と削除が実行できます。

podman pod stop tmp_pg && podman pod rm tmp_pg
0
Raw
https://www.techtips.page/en/comments/319
💡1
❤️1

HerokuでDBのアップデート等を行うときの作業の流れ

wakairo @wakairo
Last edited

PostgreSQLのメジャーバージョンを上げるときなど、通常のデータの読み書きとは異なる更新をDBに対して行うことがあります。

ここではHerokuの公式ドキュメントである「Heroku Postgres データベースのバージョンのアップグレード」を参考に、このようなアップデート等の変更をDBに行うときの大まかな流れをご紹介します。

DBにアップデート等の変更を行うときの作業の流れ

新たなDBを作成する

メジャーバージョンを上げるといった大きな更新をするときには、 何かあったときにすぐに戻せるよう、元のDBには手を入れずそのままにして温存します。 代わりに、addons:createコマンドなどで、大きな更新を行う別の新たなDBを作成します。

DBへの書き込みを停止させて、データを完璧に複製する

addons:createコマンドの--followオプションやpg:copyコマンドを利用して、 元のDBから新たなDBにデータをコピーします。 この際、適切にアプリをメンテナンスモードにするなどして、元のDBへの書き込みを停止させ、 停止している間に元のDBのデータの全てが新たなDBに複製されている状態にします。

ちなみに、公式ドキュメントには記載がありませんが、 バックアップが短時間で終わるデータの規模であるならば、 トラブルに備えてこの書き込みが停止しているタイミングで元のDBのバックアップを手動で作成しても良いように思います。

新たなDBに手を加える

メジャーバージョンの更新などの必要があれば、新たなDBに手を加えます。

アプリの接続先を元のDBから新たなDBに切り替える

pg:promoteコマンドを利用して、アプリが読み書きする対象を新たなDBに切り替えます。

アプリを公開してテストする

メンテナンスモードを解除するなどして、アプリを公開状態に戻します。 本番環境が問題なく動いているかテストを行います。 何かしら問題がある場合には、アプリの接続先を元のDBに迅速に戻すことで、被害が最小化できるはずです。

不要になったDBを削除する

元のDBなどが不要になった場合など、addons:destroyコマンドなどを利用して、不要になったDBを削除します。

(参考)ステージングアプリを利用したテスト

より安全にDBの更新などを行うために、本番のアプリのDBを更新する前に、ステージングのアプリでDBの更新をテストすることも可能です。詳細はPostgreSQL メジャーバージョンのアップグレードのテストをご覧ください。

0
Raw
https://www.techtips.page/en/comments/318
❤️1

Herokuでは環境変数DATABASE_URLを使ってrailsアプリが接続するDBの設定を行っている

wakairo @wakairo
Last edited

railsのDB接続設定では、環境変数DATABASE_URLの情報が優先されます

Herokuでは、環境変数DATABASE_URLへの設定を通してDB設定が行れています。また、このDB設定(つまり、DATABASE_URLの値)を変更したいときにはheroku pg:promote​コマンドを用います。

なお、環境変数DATABASE_URLの現在の設定値はheroku configコマンドで確認できます。

0
Raw
https://www.techtips.page/en/comments/317

tオプションを付けてPodmanからリダイレクトでバイナリ出力を取り出すと壊れる

wakairo @wakairo
Last edited

概要

Podmanで、-itオプション、厳密には-tオプションを付けっぱなしで、以下のようにリダイレクトを使うと、出力されたファイルの内容が壊れることがあります。-tオプションの意味を考えれば、出力をリダイレクトに回すときに指定する必要があるオプションではないのですが、コマンドを改変して流用するときなどに付けっぱなしにするとバイナリが壊れますのでご注意ください。

podman run -it --rm -v "$PWD":/x -w /x ruby:latest ruby print_bin.rb > podman.bin

この問題は、以下のようにtオプションを外すことで回避できます。もちろんiオプションを残さず合わせて外してもOKです。

podman run -i --rm -v "$PWD":/x -w /x ruby:latest ruby print_bin.rb > no_t.bin

また、この問題を回避方法として、以下のように、bash -cを使う方法もあります。

podman run -it --rm -v "$PWD":/x -w /x ruby:latest bash -c 'ruby print_bin.rb > bash.bin'

ちなみにこの問題は、Dockerでも起きるようです。

詳細

例として、0x00から0xffまでの256バイトのバイナリを標準出力に出力する以下のRubyスクリプトを利用します。

print_bin.rb

print (0..255).to_a.pack('C*')

Podmanを使わずに、ローカルでこのスクリプトを実行して確認すると、以下のように正しく出力されているのが分かります。

$ ruby print_bin.rb > local.bin
$ hexdump -C local.bin
00000000  00 01 02 03 04 05 06 07  08 09 0a 0b 0c 0d 0e 0f  |................|
00000010  10 11 12 13 14 15 16 17  18 19 1a 1b 1c 1d 1e 1f  |................|
00000020  20 21 22 23 24 25 26 27  28 29 2a 2b 2c 2d 2e 2f  | !"#$%&'()*+,-./|
00000030  30 31 32 33 34 35 36 37  38 39 3a 3b 3c 3d 3e 3f  |0123456789:;<=>?|
00000040  40 41 42 43 44 45 46 47  48 49 4a 4b 4c 4d 4e 4f  |@ABCDEFGHIJKLMNO|
00000050  50 51 52 53 54 55 56 57  58 59 5a 5b 5c 5d 5e 5f  |PQRSTUVWXYZ[\]^_|
00000060  60 61 62 63 64 65 66 67  68 69 6a 6b 6c 6d 6e 6f  |`abcdefghijklmno|
00000070  70 71 72 73 74 75 76 77  78 79 7a 7b 7c 7d 7e 7f  |pqrstuvwxyz{|}~.|
00000080  80 81 82 83 84 85 86 87  88 89 8a 8b 8c 8d 8e 8f  |................|
00000090  90 91 92 93 94 95 96 97  98 99 9a 9b 9c 9d 9e 9f  |................|
000000a0  a0 a1 a2 a3 a4 a5 a6 a7  a8 a9 aa ab ac ad ae af  |................|
000000b0  b0 b1 b2 b3 b4 b5 b6 b7  b8 b9 ba bb bc bd be bf  |................|
000000c0  c0 c1 c2 c3 c4 c5 c6 c7  c8 c9 ca cb cc cd ce cf  |................|
000000d0  d0 d1 d2 d3 d4 d5 d6 d7  d8 d9 da db dc dd de df  |................|
000000e0  e0 e1 e2 e3 e4 e5 e6 e7  e8 e9 ea eb ec ed ee ef  |................|
000000f0  f0 f1 f2 f3 f4 f5 f6 f7  f8 f9 fa fb fc fd fe ff  |................|
00000100

では、Podmanで動かした出力をリダイレクトさせてみたものを確認するとどうなっているかといいますと、 0x09の後に0x0dが増えてしまっており、ファイルの中身が壊れていることがわかります。

$ podman run -it --rm -v "$PWD":/x -w /x ruby:latest ruby print_bin.rb > podman.bin
$ hexdump -C podman.bin
00000000  00 01 02 03 04 05 06 07  08 09 0d 0a 0b 0c 0d 0e  |................|
00000010  0f 10 11 12 13 14 15 16  17 18 19 1a 1b 1c 1d 1e  |................|
00000020  1f 20 21 22 23 24 25 26  27 28 29 2a 2b 2c 2d 2e  |. !"#$%&'()*+,-.|
00000030  2f 30 31 32 33 34 35 36  37 38 39 3a 3b 3c 3d 3e  |/0123456789:;<=>|
00000040  3f 40 41 42 43 44 45 46  47 48 49 4a 4b 4c 4d 4e  |?@ABCDEFGHIJKLMN|
00000050  4f 50 51 52 53 54 55 56  57 58 59 5a 5b 5c 5d 5e  |OPQRSTUVWXYZ[\]^|
00000060  5f 60 61 62 63 64 65 66  67 68 69 6a 6b 6c 6d 6e  |_`abcdefghijklmn|
00000070  6f 70 71 72 73 74 75 76  77 78 79 7a 7b 7c 7d 7e  |opqrstuvwxyz{|}~|
00000080  7f 80 81 82 83 84 85 86  87 88 89 8a 8b 8c 8d 8e  |................|
00000090  8f 90 91 92 93 94 95 96  97 98 99 9a 9b 9c 9d 9e  |................|
000000a0  9f a0 a1 a2 a3 a4 a5 a6  a7 a8 a9 aa ab ac ad ae  |................|
000000b0  af b0 b1 b2 b3 b4 b5 b6  b7 b8 b9 ba bb bc bd be  |................|
000000c0  bf c0 c1 c2 c3 c4 c5 c6  c7 c8 c9 ca cb cc cd ce  |................|
000000d0  cf d0 d1 d2 d3 d4 d5 d6  d7 d8 d9 da db dc dd de  |................|
000000e0  df e0 e1 e2 e3 e4 e5 e6  e7 e8 e9 ea eb ec ed ee  |................|
000000f0  ef f0 f1 f2 f3 f4 f5 f6  f7 f8 f9 fa fb fc fd fe  |................|
00000100  ff                                                |.|
00000101

この問題を回避するために、今度は以下のように-tオプションを外します。 無事に正しく出力できていることが分かります。

$ podman run -i --rm -v "$PWD":/x -w /x ruby:latest ruby print_bin.rb > no_t.bin
wakairo@DESKTOP-633O7R3:~/tmp$ hexdump -C no_t.bin
00000000  00 01 02 03 04 05 06 07  08 09 0a 0b 0c 0d 0e 0f  |................|
00000010  10 11 12 13 14 15 16 17  18 19 1a 1b 1c 1d 1e 1f  |................|
00000020  20 21 22 23 24 25 26 27  28 29 2a 2b 2c 2d 2e 2f  | !"#$%&'()*+,-./|
00000030  30 31 32 33 34 35 36 37  38 39 3a 3b 3c 3d 3e 3f  |0123456789:;<=>?|
00000040  40 41 42 43 44 45 46 47  48 49 4a 4b 4c 4d 4e 4f  |@ABCDEFGHIJKLMNO|
00000050  50 51 52 53 54 55 56 57  58 59 5a 5b 5c 5d 5e 5f  |PQRSTUVWXYZ[\]^_|
00000060  60 61 62 63 64 65 66 67  68 69 6a 6b 6c 6d 6e 6f  |`abcdefghijklmno|
00000070  70 71 72 73 74 75 76 77  78 79 7a 7b 7c 7d 7e 7f  |pqrstuvwxyz{|}~.|
00000080  80 81 82 83 84 85 86 87  88 89 8a 8b 8c 8d 8e 8f  |................|
00000090  90 91 92 93 94 95 96 97  98 99 9a 9b 9c 9d 9e 9f  |................|
000000a0  a0 a1 a2 a3 a4 a5 a6 a7  a8 a9 aa ab ac ad ae af  |................|
000000b0  b0 b1 b2 b3 b4 b5 b6 b7  b8 b9 ba bb bc bd be bf  |................|
000000c0  c0 c1 c2 c3 c4 c5 c6 c7  c8 c9 ca cb cc cd ce cf  |................|
000000d0  d0 d1 d2 d3 d4 d5 d6 d7  d8 d9 da db dc dd de df  |................|
000000e0  e0 e1 e2 e3 e4 e5 e6 e7  e8 e9 ea eb ec ed ee ef  |................|
000000f0  f0 f1 f2 f3 f4 f5 f6 f7  f8 f9 fa fb fc fd fe ff  |................|
00000100

この問題を回避するために、今度は以下のようにbash -cを使ってみます。 こちらでも無事に正しく出力できていることが分かります。

$ podman run -it --rm -v "$PWD":/x -w /x ruby:latest bash -c 'ruby print_bin.rb > bash.bin'
$ hexdump -C bash.bin
00000000  00 01 02 03 04 05 06 07  08 09 0a 0b 0c 0d 0e 0f  |................|
00000010  10 11 12 13 14 15 16 17  18 19 1a 1b 1c 1d 1e 1f  |................|
00000020  20 21 22 23 24 25 26 27  28 29 2a 2b 2c 2d 2e 2f  | !"#$%&'()*+,-./|
00000030  30 31 32 33 34 35 36 37  38 39 3a 3b 3c 3d 3e 3f  |0123456789:;<=>?|
00000040  40 41 42 43 44 45 46 47  48 49 4a 4b 4c 4d 4e 4f  |@ABCDEFGHIJKLMNO|
00000050  50 51 52 53 54 55 56 57  58 59 5a 5b 5c 5d 5e 5f  |PQRSTUVWXYZ[\]^_|
00000060  60 61 62 63 64 65 66 67  68 69 6a 6b 6c 6d 6e 6f  |`abcdefghijklmno|
00000070  70 71 72 73 74 75 76 77  78 79 7a 7b 7c 7d 7e 7f  |pqrstuvwxyz{|}~.|
00000080  80 81 82 83 84 85 86 87  88 89 8a 8b 8c 8d 8e 8f  |................|
00000090  90 91 92 93 94 95 96 97  98 99 9a 9b 9c 9d 9e 9f  |................|
000000a0  a0 a1 a2 a3 a4 a5 a6 a7  a8 a9 aa ab ac ad ae af  |................|
000000b0  b0 b1 b2 b3 b4 b5 b6 b7  b8 b9 ba bb bc bd be bf  |................|
000000c0  c0 c1 c2 c3 c4 c5 c6 c7  c8 c9 ca cb cc cd ce cf  |................|
000000d0  d0 d1 d2 d3 d4 d5 d6 d7  d8 d9 da db dc dd de df  |................|
000000e0  e0 e1 e2 e3 e4 e5 e6 e7  e8 e9 ea eb ec ed ee ef  |................|
000000f0  f0 f1 f2 f3 f4 f5 f6 f7  f8 f9 fa fb fc fd fe ff  |................|
00000100
1
Raw
https://www.techtips.page/en/comments/316
💯1

Heroku CLIをaptでインストールすると自動更新されない

wakairo @wakairo

2024年9月現在、UbuntuやDebianでapt-getを使ってインストールしたHeroku CLIは自動更新されなくなっています。具体的には、単純にsudo apt-get upgradeを走らせるだけでは、最新版になりませんでした。昔はこのコマンドで最新版に更新されたと思うのですが。

https://devcenter.heroku.com/ja/articles/heroku-cli#install-with-ubuntu-debian-apt-get には以下の記述があります。

このバージョンでは、自動更新を行いません。apt-get​を使用して手動で更新してください。

そして、自動更新をして欲しい場合には、tar 書庫によるスタンドアロンインストールを使えば良いそうです。ということで、特に事情がない分には、今後はこちらのスタンドアロンインストール版の方が便利そうです。

0
Raw
https://www.techtips.page/en/comments/315
😄1
🔧1

railsが挿入するfield_with_errorsの要素がBootstrapのinput-groupの表示を乱す問題

wakairo @wakairo
Last edited

問題の内容

フォームヘルパーで作成したフォームの標準の挙動として、 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)
0
Raw
https://www.techtips.page/en/comments/314
💡1
❤️1

Railsで複数のセッションを用いたintegration testを行う方法

wakairo @wakairo
Last edited

別々のブラウザから複数のユーザがログインするような状況を再現した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
0
Raw
https://www.techtips.page/en/comments/313
❤️1