rails

Ruby on Rails

Create a Topic

Topics

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

479 views Post
wakairo @wakairo

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

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

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

0
Raw
https://www.techtips.page/en/comments/649
😄3
🔧1
💯1
❤️1
wakairo @wakairo

不要であればアイコン画像の削除

bin/rails app:updateコマンドを実行すると以下の2つのアイコン画像ファイルがpublic/に作成されますが、
これら2つのファイルは、rails newで生成される新規railsアプリ用のファイルであるため、既存アプリでは単純に削除してしまい、 従来通りのアイコン画像とアイコン設定(faviconやapple-touch-icon)を用いれば大丈夫です。 (もちろん、既存アプリにおいてアイコン設定が適切に行われている場合の話です。)

  • icon.png
  • icon.svg

より詳細な情報はrails 7.2への移行におけるアイコン画像のコメントをご覧ください。

0
Raw
https://www.techtips.page/en/comments/650
wakairo @wakairo

Rails 8.0への移行におけるActive Storageのmigration

bin/rails app:updateコマンドを実行すると以下の3つのファイルがdb/migrate/に作成されることがありますが、
Active Storageをまだ使用したことがないアプリケーションでは、 これら3つのファイルは単純に削除してしまっても良いはずです。

  • xxx_add_service_name_to_active_storage_blobs.active_storage.rb
  • xxx_create_active_storage_variant_records.active_storage.rb
  • xxx_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb

詳しくは、「Rails 7.1への移行におけるActive Storageのmigration」のコメントをご覧ください。

0
Raw
https://www.techtips.page/en/comments/651
wakairo @wakairo

Rails 8.0ではfilter_parametersに:cvvと:cvcが追加された

rails newで生成されるconfig/initializers/filter_parameter_logging.rbにおいて、 Rails 8.0でconfig.filter_parameters:cvv:cvcが追加されました。 この追加に関するプルリクエストはこちらです

セキュリティの観点からは、確かにクレジットカードのCVCとCVVをフィルタすることは適切であるように思いますので、既存アプリにおいても:cvvと:cvcを追加すると良さそうです。

0
Raw
https://www.techtips.page/en/comments/652
wakairo @wakairo

Rails 8.0におけるdeprecation関連の設定の削除

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

  # Raise exceptions for disallowed deprecations.
  config.active_support.disallowed_deprecation = :raise

  # Tell Active Support which deprecation messages to disallow.
  config.active_support.disallowed_deprecation_warnings = []

削除された理由は、当該プルリクエストによると、アプリが新規生成された直後は非推奨の問題と無縁であるということからのようです。 ですので、非推奨の問題が出てくる可能性のある既存アプリにおいては適切な設定をしたままにしておくのが良さそうです。

0
Raw
https://www.techtips.page/en/comments/653
wakairo @wakairo

Rails 8.0におけるpublic_file_server.headersの設定の変更

rails newで生成されるconfig/environments/test.rbと同development.rbにおいて、 このプルリクエストのマージによって、 config.public_file_server.headersのキーが以下のように小文字になりました。

-    config.public_file_server.headers = { "Cache-Control" => "public, max-age=#{2.days.to_i}" }
+    config.public_file_server.headers = { "cache-control" => "public, max-age=#{2.days.to_i}" }

変更された理由はRack 3への対応のためですので、既存アプリでも設定を変更するのが良さそうです。

0
Raw
https://www.techtips.page/en/comments/654
wakairo @wakairo

Rails 8.0におけるquery_log_tags_enabled

config.active_record.query_log_tags_enabledは、SQLクエリのログに実行時情報のコメントを付加する機能を有効にするかどうかの設定です。

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

  # Append comments with runtime information tags to SQL queries in logs.
  config.active_record.query_log_tags_enabled = true

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

0
Raw
https://www.techtips.page/en/comments/655
wakairo @wakairo

Rails 8.0におけるassets.quiet

config.assets.quietは、アセット関連リクエストのログ出力を無効にするかどうかの設定です。後述のように、Rails 8.0.0でtrueにする以下の設定が削除されましたが、復活させるPRが出ていますので、既存アプリで削除するかには慎重な判断が必要かもしれません。

  # Suppress logger output for asset requests.
  config.assets.quiet = true

rails newで生成されるconfig/environments/development.rbにおいて、 8.0.0と8.0.1ではこの設定が削除されています(この変更のPR)。 しかし、この設定を削除するとターミナル出力がとっちらかるので設定を復活させるというPRがマージ済みですので、今後のバージョンでは設定が復活します。

0
Raw
https://www.techtips.page/en/comments/656
wakairo @wakairo
Last edited

Rails 8.0におけるaction_controller.perform_cachingとaction_mailer.perform_caching

config.action_controller.perform_cachingconfig.action_mailer.perform_cachingは、両方ともキャッシュ機能を有効にするかどうかの設定です。

rails newで生成されるconfig/environments/test.rbにおいて、 8.0からは以下のようにこれらの設定を無効にするコードが削除されました(この変更のPRこの変更のCommit)。

-  # Show full error reports and disable caching.
+  # Show full error reports.
   config.consider_all_requests_local = true
-  config.action_controller.perform_caching = false
   config.cache_store = :null_store
-  # Disable caching for Action Mailer templates even if Action Controller
-  # caching is enabled.
-  config.action_mailer.perform_caching = false

公式として8.0からはテスト環境ではキャッシュが効いた状態を標準とするということだと思いますので、既存アプリでも同じ設定変更、つまり、設定の削除をしても良いかもしれません。

0
Raw
https://www.techtips.page/en/comments/657
wakairo @wakairo

Rails 8.0におけるassets.compile

config.assets.compileは、動的なSprocketsコンパイルを有効にするかどうかの設定です。

rails newで生成されるconfig/environments/production.rbにおいて、 8.0からは以下のようにこの設定が削除されているのですが(この変更のPRこの変更のCommit)、 これは8.0からrails newで生成されるアプリのアセットパイプラインのデフォルトがPropshaftになったことに起因するものです。

-  # Do not fall back to assets pipeline if a precompiled asset is missed.
-  config.assets.compile = false

ですので既存アプリは、Propshaftへ移行する前はこの設定は削除しない方が良いと思われます。

0
Raw
https://www.techtips.page/en/comments/658
wakairo @wakairo
Last edited

Rails 8.0におけるpublic_file_server.headersとassume_ssl

rails newで生成されるconfig/environments/production.rbにおいて、 8.0からは以下の設定2つが追加されているのですが(この変更のPRこの変更のCommit)、 これは8.0からrails newで生成されるアプリでKamal 2対応が行われていることに起因するものです。

+  # Cache assets for far-future expiry since they are all digest stamped.
+  config.public_file_server.headers = { "cache-control" => "public, max-age=#{1.year.to_i}" }
   # Assume all access to the app is happening through a SSL-terminating reverse proxy.
-  # Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies.
-  # config.assume_ssl = true
+  config.assume_ssl = true

ですので既存アプリでは、Kamal 2対応をしないのであればこれらの設定の追加はしなくても良いと思われます。

0
Raw
https://www.techtips.page/en/comments/659
wakairo @wakairo
Last edited

Rails 8.0におけるsilence_healthcheck_path

config.silence_healthcheck_pathは、ログ出力を抑制すべきヘルスチェックのパスを指定する設定です。

rails newで生成されるconfig/environments/production.rbにおいて、 8.0からは以下のようにこの設定を行うコードが追加されました(この変更のPRこの変更のCommit)。

  # Prevent health checks from clogging up the logs.
  config.silence_healthcheck_path = "/up"

ヘルスチェックでログが詰まる問題が起きている場合や見やすさなどの理由でヘルスチェックのログを抑制をしたい場合は既存アプリでも同じ設定変更、つまり、設定の追加をしても良いかもしれません。

0
Raw
https://www.techtips.page/en/comments/660
wakairo @wakairo
Last edited

Rails 8.0におけるaction_mailer.perform_caching

config.action_mailer.perform_cachingは、メーラーテンプレートでフラグメントキャッシングを行うかどうかの設定です。

rails newで生成されるconfig/environments/production.rbにおいて、 8.0からは以下のようにこの設定を行うコードが削除されました(この変更のPRこの変更のCommit)。このキャッシングを無効にするコードの削除により、メーラーテンプレートでのフラグメントキャッシングが有効になります。

-  # Disable caching for Action Mailer templates even if Action Controller
-  # caching is enabled.
-  config.action_mailer.perform_caching = false

既存アプリでもメーラーテンプレートでのフラグメントキャッシングを有効にしたい場合は、このコードの削除により可能です。

0
Raw
https://www.techtips.page/en/comments/661
wakairo @wakairo

Rails 8.0におけるactive_record.attributes_for_inspect

config.active_record.attributes_for_inspectは、Active Recordオブジェクトのinspectに関わる設定です。

rails newで生成されるconfig/environments/production.rbにおいて、 8.0からこの設定を行う以下のコードが追加されました(この変更のPR)。このコードの追加により、production環境ではinspectの結果に基本的にidのみが含まれるようになります。

  # Only use :id for inspections in production.
  config.active_record.attributes_for_inspect = [ :id ]

この設定はproduction環境でのパフォーマンスの悪化をさけるための変更に端を発していますので、既存アプリでもこのコードを追加すると良いかもしれません。

0
Raw
https://www.techtips.page/en/comments/662
wakairo @wakairo

Rails 8.0におけるlogger

config.loggerは、Railsアプリで用いるロガーの設定です。

rails newで生成されるconfig/environments/production.rbにおいて、 8.0からこの設定について以下の変更が行われました(この変更のPRその1PRその2)。この変更により、Kamralを用いたproduction環境ではタイムスタンプが二重に表示されなくなります。

-  # Log to STDOUT by default
-  config.logger = ActiveSupport::Logger.new(STDOUT)
-    .tap  { |logger| logger.formatter = Logger::Formatter.new }
-    .then { |logger| ActiveSupport::TaggedLogging.new(logger) }
-
-  # Prepend all log lines with the following tags.
+  # Log to STDOUT with the current request id as a default log tag.
   config.log_tags = [ :request_id ]
+  config.logger   = ActiveSupport::TaggedLogging.logger(STDOUT)

既存アプリでも、production環境でタイムスタンプが二重になっている場合には、この変更を行ってタイムスタンプが1つになるようにすると良いかもしれません。

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

rails 7.2で追加されたGitHubワークフローの設定ファイルci.ymlの内容について

373 views Post
wakairo @wakairo

rails 7.2では、新規アプリに対してデフォルトでGitHubワークフローの設定ファイルであるci.ymlが生成されるようになりました。そこで、このci.ymlの内容について簡単に解説します。

なお、ci.ymlの最新のテンプレートはこちらでご覧になれます

scan_ruby

bin/brakemanコマンドを実行するジョブです。 Railsの一般的なセキュリティ脆弱性がないかどうかチェックします。

scan_js

bin/importmap auditコマンドを実行するジョブです。 利用しているJavaScriptパッケージにセキュリティ上の脆弱性がないかどうかチェックします。

lint

bin/rubocopコマンドを実行するジョブです。 Rubyの静的コード解析を行い設定されているルールに準拠しているかどうかチェックします。

test

bin/rails testコマンドを実行するジョブです。なお、skip_system_testオプションが無効であれば、システムテストも実行します。

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

既存のRailsアプリへのDev Containerの導入

371 views Post
wakairo @wakairo

Rails 7.2においてDev Container設定を生成する機能が追加されました。 例えば既存アプリでは、以下のコマンドで既存アプリ用のDev Container設定を生成できるようになりました。

rails devcontainer

生成した設定は、Visual Studio Codeで利用でき、Dev Containerを利用した既存アプリの開発が可能となります。 必要となるソフトウェアのインストール等、Dev Containerでの開発を開始するための手順についてはDev Containerでの開発ガイドが参考になります。

なお、Visual Studio Code以外のエディタでもDev Containerで開発できるようにするべくDev Container CLIというツールの開発が進んでいますが、2024年12月現在では、ポートフォワーディングに対応していないなど、今のところはまだまだ開発途中のツールであり、実開発に投入するにはまだ早い段階である印象です。

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

既存のRailsアプリへのRuboCopの導入

537 views Post
wakairo @wakairo
Last edited

Rails 7.2からRuboCopが新規アプリケーションでデフォルトで有効になりました。 このTopicでは、7.1以前で作成した既存RailsアプリにRuboCopを後から導入して、RuboCopに関して7.2の新規アプリ相当の状態にセットアップする方法をご紹介します。

RuboCop (Omakase Ruby styling for Rails) のインストール

基本的にはrubocop-rails-omakaseの公式ドキュメントのインストール手順に従います。

まず以下のように、Gemfileのgroup :development, :testのところにrubocop-rails-omakaseを追加します。

group :development, :test do

  # Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/]
  gem "rubocop-rails-omakase", require: false

end

次にbundle installを実行して、RuboCop等をインストールします。

bundle install

さらに、必須ではありませんが、bin/rubocopでRuboCopを実行できるように、以下のコマンドを実行します。

bundle binstubs rubocop

最後に.rubocop.ymlという名前でファイルを作成し、以下の内容を記述します。

# Omakase Ruby styling for Rails
inherit_gem:
  rubocop-rails-omakase: rubocop.yml

以上でRuboCop (Omakase Ruby styling for Rails) のセットアップが出来ました。

ローカル環境でのbin/rubocopの実行とその結果に対する対応の進め方

以下のコマンドでbin/rubocopを実行でき、omakaseのチェックを行えます。

bin/rubocop

このチェックでの指摘事項が多かった場合、以下のオプションを付けて実行することで、 無視設定を記述した.rubocop_todo.ymlというファイルが作成され、 .rubocop.ymlにもこの無視ファイルを参照する設定が追加されますので、 とりあえず全ての指摘事項を無視するように設定が出来ます。

bin/rubocop --auto-gen-config

設定が出来たら、bin/rubocopを実行して、とりあえず指摘事項の数が0となることを確認します。

1つずつ指摘事項へ対応

ここから先は、以下の手順を繰り返します。

1項目ずつ対応を進め、.rubocop_todo.ymlの中身が無くなったら、.rubocop_todo.ymlを削除すると共に、.rubocop.yml内で.rubocop_todo.ymlを参照している設定を削除します。ここまで終わればRuboCopの諸規則への対応は完了となります。お疲れ様でした。

GitHubワークフロー(CI)でのrubocopの実行

.github/workflows/ci.ymlに相当するファイルがなければ作成します。 この.ymlファイルを編集して、以下のようにjobsの下にlintジョブを追加します。

注意点
jobs:
  lint:
    runs-on: ubuntu-latest
    timeout-minutes: 10

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: .ruby-version
          bundler-cache: true

      - name: Lint code for consistent style
        run: bin/rubocop -f github

公式情報

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

既存のRailsアプリでのDependabotへの対応

674 views Post
wakairo @wakairo
Last edited

Rails 7.2から新規アプリケーションにおいてDependabotがデフォルトで有効になりました。 具体的には、rails newで生成される新規アプリにおいて、Dependabotの設定ファイルである.github/dependabot.ymlが生成されるようになりました。

Dependabotとは

Dependabotとは、GitHubのサービスであり、リポジトリで使用しているソフトウェアを最新の状態に保つことをサポートしてくれるサービスです。 具体的なDependabotの機能としては、以下の3つがあります

  • Dependabot alerts — リポジトリで使っている依存関係に内在する脆弱性について通知します。
  • Dependabot security updates — 使っている依存関係のうち、既知のセキュリティ脆弱性があるものを更新するための pull request を自動的に生成します。
  • Dependabot version updates — 依存関係を最新に保つための pull request を自動的に発行します。

Dependabotの詳細な理解にはクイックスタート ガイドなどをご利用ください。

既存のRailsアプリでのDependabotへの対応方法

脆弱性の通知機能(Dependabot alerts)は、GitHubのWebページから設定を変更するだけで利用できます

脆弱性に関するpull requestの自動生成機能(Dependabot security updates)も、GitHubのWebページから設定を変更するだけで利用できますが、詳細な設定が必要な場合はdependabot.ymlを通して行います

脆弱性対応以外も含めて最新の状態にするためのpull requestを自動生成する機能(Dependabot version updates)は、dependabot.ymlを通した設定が必要です

(参考)デフォルトのdependabot.ymlの内容

このリンク先で閲覧できるrails newで生成される新規アプリのdependabot.ymlの設定内容は、既存アプリでも参考になるかもしれません。 このdependabot.ymlには、Rails 7.2の時点では、railsアプリで利用しているgemとGitHub Actions(GitHubのCI)で利用しているアクションを最新に保つための設定が記述されています。

0
Raw
https://www.techtips.page/en/comments/447
😄3
🔄1
🔧1
💡1
💯1

既存のRailsアプリへのBrakemanの導入

792 views Post
wakairo @wakairo
Last edited

Rails 7.2から新規アプリケーションにおいてBrakemanがデフォルトで有効になりました。 このTopicでは、7.1以前で作成した既存RailsアプリにBrakemanを後から導入して、Brakemanに関して7.2の新規アプリ相当の状態にセットアップする方法をご紹介します。

Brakemanのインストール

まず以下のように、Gemfileのgroup :development, :testのところにbrakemanを追加します。

group :development, :test do

  # Static analysis for security vulnerabilities [https://brakemanscanner.org/]
  gem "brakeman", require: false

end

次にbundle installを実行します。

bundle install

以上でBrakemanのインストールが出来ました。

さらに、必須ではありませんが、bin/brakemanでBrakemanを実行できるように、以下のコマンドを実行します。

bundle binstubs brakeman

ローカル環境でのBrakemanの実行

以下のコマンドでBrakemanを実行でき、デフォルトのチェックを行えます。

bin/brakeman

全てのチェックを実行する場合には、以下のオプション付けて実行します。

bin/brakeman -A

警告の無視に関する設定と管理を行う場合は、以下のオプション付けて実行します。

bin/brakeman -I

以下のように、これら2つのオプションを同時に指定して実行することも出来ます。

bin/brakeman -IA

なお、Brakemanの詳細については公式ドキュメントをご覧ください。 また、brakemanコマンドのオプションについては日本語訳もあります。

GitHubワークフロー(CI)でのBrakemanの実行

.github/workflows/ci.ymlに相当するファイルがなければ作成します。 この.ymlファイルを編集して、以下のようにjobsの下にscan_rubyジョブを追加します。

ymlファイルの設定に関する注意点
  • timeout-minutes:の設定は、実行時間に対して十分余裕を持たせて下さい。
  • ruby-version: .ruby-version」という設定は、プロジェクトルートにある.ruby-versionという名前のファイルで指定されているrubyのバージョンという意味になります。この設定についての詳細はこちらのTopicをご覧下さい。
jobs:
  scan_ruby:
    runs-on: ubuntu-latest
    timeout-minutes: 10

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: .ruby-version
          bundler-cache: true

      - name: Scan for common Rails security vulnerabilities using static analysis
        run: bin/brakeman --no-pager
0
Raw
https://www.techtips.page/en/comments/418
🔧3
😄2
💡1
💯1
❤️1
wakairo @wakairo

bundle binstubs brakemanを用いるやり方に更新しました。

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

Rails 7.1では、パスワードに関してエラーメッセージの種類が増えた

1261 views Post
wakairo @wakairo
Last edited

Rails 7.1に取り込まれたこちらのプルリクエストによって、 ActiveModel::SecurePasswordhas_secure_passwordメソッドを利用している場合のパスワードのバリデーションにおいて、 パスワード文字列が72バイト以内かどうかのチェックが行われるようになりました。 そして、72バイトを超えている場合には、password_too_longという新しい種類のエラーが出るようになりました。

この変更に伴って、日本語表示のRailsアプリでは、password_too_longのエラーメッセージの日本語訳を用意する必要があります。 具体的には、以下の階層の所に以下のような日本語訳が必要となります。

ja:
  errors:
    messages:
      password_too_long: が長すぎます
0
Raw
https://www.techtips.page/en/comments/332
🔄1
🔧1

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

1631 views Post
wakairo @wakairo
Last edited

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

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

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

0
Raw
https://www.techtips.page/en/comments/320
😄2
❤️2
🔧1
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
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
wakairo @wakairo
Last edited

rails 7.2ではfilter_parametersに:emailが追加された

rails newで生成されるconfig/initializers/filter_parameter_logging.rbにおいて、 rails 7.2でconfig.filter_parameters:emailが追加されました。 この追加に関するプルリクエストはこちらです。

 Rails.application.config.filter_parameters += [
-  :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
+  :passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
 ]

セキュリティや個人情報保護の観点からは、確かにメールアドレスをフィルタすることは適切であるように思いますので、既存アプリにおいても:emailを追加すると良さそうです。

ちなみに、デバッグ作業などでメールアドレスを確認するときには少し不便になるような気もしますが、 emailへの直接の読み書きが疎外されるわけではありませんし、 またpluckなどの活用もすればデバッグの支障にはさほどならないような気がします。

0
Raw
https://www.techtips.page/en/comments/323
wakairo @wakairo
Last edited

rails 7.2でのconfig/puma.rbの大幅な更新

rails newで生成されるconfig/puma.rbが大幅に更新されました。

主要な変更点は以下の通りです。

0
Raw
https://www.techtips.page/en/comments/324
wakairo @wakairo
Last edited

rails 7.2への移行におけるActive Storageのmigration

bin/rails app:updateコマンドを実行すると以下の3つのファイルがdb/migrate/に作成されることがありますが、
Active Storageをまだ使用したことがないアプリケーションでは、 これら3つのファイルは単純に削除してしまっても良いはずです。

  • xxx_add_service_name_to_active_storage_blobs.active_storage.rb
  • xxx_create_active_storage_variant_records.active_storage.rb
  • xxx_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb

より正確に言うと、データベースにactive_storage_blobsテーブルが存在していない場合は、 これら3つのファイルは単純に削除してしまっても良いはずです。 その理由として、これら3つのファイルはデータベースのactive_storage_blobsテーブルに対して影響を与えるものであり、 table_exists?(:active_storage_blobs)がfalseを返すと何もせずにreturnする処理が3つのファイル全てに記述されているからです。

ご自身のRailsアプリケーションのデータベースにactive_storage_blobsテーブルが存在するかの確認はbin/rails consoleを実行して、 以下のようにコマンドを実行することで行えます。 結果がfalseであればactive_storage_blobsテーブルは存在していない、つまり前述の3つのファイルは削除で大丈夫のはずです。

foobar(dev)> ActiveRecord::Base.connection.table_exists? :active_storage_blobs
=> false

ちなみに、データベースにあるテーブルの一覧を見たい場合にはbin/rails consoleActiveRecord::Base.connection.tablesを叩くことでテーブルの一覧を確認できます。

0
Raw
https://www.techtips.page/en/comments/325
wakairo @wakairo
Last edited

rails 7.2で追加されたブラウザバージョン指定機能と406-unsupported-browser.html

bin/rails app:updateコマンドを実行するとpublic/に406-unsupported-browser.html作成されます。 このHTMLフィアルは、rails 7.2で追加されたブラウザバージョン指定機能が指定範囲外のブラウザに対して送るファイルです。

なお、既存アプリでは、この機能の利用を始めないのであれば、念のため406-unsupported-browser.htmlを置くだけ置いておくという対応で良いように思います。

0
Raw
https://www.techtips.page/en/comments/326
wakairo @wakairo
Last edited

rails 7.2ではassertionがないテストに対して警告が出るようになった

現象

rails 7.2では、Minitestを使ったテストに関して、assert系メソッドが1つも呼ばれないテストがあると"Test is missing assertions"という警告が出るようになりました。

警告が出ないようにする方法

各テストでassert系メソッドが最低1回は実際に呼ばれるようにして下さい。 例外が起きないことを確認するテストではassert_nothing_raisedメソッドを用いて下さい。 なお、警告の回避方法を含め、こちらの記事が参考になるかもしれません。

関連するプルリクエストとコミット

この機能はPR #51625で導入され、このときはrailsアプリの設定によって挙動を変えられるようになっていました。 その後、commit 6a6c7e6によって機能が単純化され、単に常に警告が出力されるだけになりました。 その後、PR #51693で関係するコードを綺麗にする作業などが行われています。

0
Raw
https://www.techtips.page/en/comments/327
wakairo @wakairo
Last edited

rails 7.2への移行におけるアイコン画像

bin/rails app:updateコマンドを実行すると以下の2つのアイコン画像ファイルがpublic/に作成されますが、
これら2つのファイルは、rails newで生成される新規railsアプリ用のファイルであるため、既存アプリでは単純に削除してしまい、 従来通りのアイコン画像とアイコン設定(faviconやapple-touch-icon)を用いれば大丈夫です。 (もちろん、既存アプリにおいてアイコン設定が適切に行われている場合の話です。)

  • icon.png
  • icon.svg

ちなみに、以下の通りrails 7.2では、新規アプリのアイコン設定が大幅に更新されています。 rails 7.2のこの新たなアイコン設定は、既存アプリにおいてもアイコン設定を見直す際に役立つかもしません。

(参考)rails 7.2.1の新規アプリのアイコン設定

以下が、新規アプリ用のテンプレートファイルからコピーしたrails 7.2.1の新規アプリのアイコン設定です。

    <link rel="manifest" href="/manifest.json">
    <link rel="icon" href="/icon.png" type="image/png">
    <link rel="icon" href="/icon.svg" type="image/svg+xml">
    <link rel="apple-touch-icon" href="/icon.png">

新たなアイコン画像ファイルによるアイコン設定に関与しているプルリクエストは、 PR #50526PR #50629です。 3つのアイコン画像ファイル(apple-touch-icon-precomposed.png、apple-touch-icon.png、favicon.ico)が削除され、 2つのアイコン画像ファイル(icon.png、icon.svg)が追加されています。 また、manifestに関しては、PWAに関する新機能に関連して導入されています。

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

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

1317 views Post
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を行う方法

1331 views Post
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