Rubyの演算でハマったこと

Rubyの演算でハマったこと

開発中にRubyの演算でとてもハマったことがあったので、備忘録としてこちらにまとめます。

下記のようなコードで具体例を示します。

((count / cookware_capacity).ceil -1) * cooking_time + cooking_total_time

[1] pry(#<CalculateCookingTime>)> count
=> 40
[2] pry(#<CalculateCookingTime>)> cookware_capacity
=> 20.0
[3] pry(#<CalculateCookingTime>)> (count / cookware_capacity)
=> 2.0
[4] pry(#<CalculateCookingTime>)> (count / cookware_capacity).ceil
=> 2
[5] pry(#<CalculateCookingTime>)> ((count / cookware_capacity).ceil -1)
=> 10

ん?。。。
((40 / 20.0).ceil -1)だから2 -1になって、1になるはずなんだが。。。

実際に数値を入れて計算させると以下のようになる。

[1] pry(#<CalculateCookingTime>)> ((40 / 20.0).ceil -1)
=> 10

やはり10になる。。。

色々試したところ、((count / cookware_capacity).ceil -1)-1の間にスペースを入れ忘れており、これが原因になっていた。

[1] pry(#<CalculateCookingTime>)> ((count / cookware_capacity).ceil - 1)
=> 1

[2] pry(#<CalculateCookingTime>)> ((40 / 20.0).ceil - 1)
=> 1

スペースを入れるのと入れないので、演算結果が異なる原因は分からなかったが、それで演算結果が変わるという事実を知りました!!
試しに-の左右両方にスペースを入れずに試した結果が以下になる。

[1] pry(#<CalculateCookingTime>)> ((count / cookware_capacity).ceil-1)
=> 1
[2] pry(#<CalculateCookingTime>)> ((40 / 20.0).ceil-1)
=> 1

上記より正しい結果になることが分かった!!
マイナス-の左右でスペースを入れたり、入れなかったりで混ぜてしまうと演算結果が正しくならないらしい。。。

herokuでのデプロイ

herokuでのデプロイ

herokuでのデプロイ時にエラーになり、つまってしまったので備忘録としてまとめます。

herokuデプロイ時のログは、以下のようになります。

-----> Building on the Heroku-22 stack
-----> Determining which buildpack to use for this app
 !     Warning: Multiple default buildpacks reported the ability to handle this app. The first buildpack in the list below will be used.
            Detected buildpacks: Ruby,Node.js
            See https://devcenter.heroku.com/articles/buildpacks#buildpack-detect-order
-----> Ruby app detected
-----> Installing bundler 2.3.10
-----> Removing BUNDLED WITH version in the Gemfile.lock
-----> Compiling Ruby/Rails
-----> Using Ruby version: ruby-3.1.2
-----> Installing dependencies using bundler 2.3.10
       Running: BUNDLE_WITHOUT='development:test' BUNDLE_PATH=vendor/bundle BUNDLE_BIN=vendor/bundle/bin BUNDLE_DEPLOYMENT=1 bundle install -j4
       Fetching gem metadata from https://rubygems.org/.........
       Fetching rake 13.0.6
       Installing rake 13.0.6
       Fetching concurrent-ruby 1.1.9
       Fetching thread_safe 0.3.6
       Fetching minitest 5.14.4
       Fetching zeitwerk 2.4.2
       Installing minitest 5.14.4
       Installing thread_safe 0.3.6
       Installing concurrent-ruby 1.1.9
       Fetching builder 3.2.4
       Installing zeitwerk 2.4.2
       Fetching erubi 1.10.0
       Installing builder 3.2.4
       Fetching mini_portile2 2.6.1
       Fetching racc 1.5.2
       Installing erubi 1.10.0
       Installing mini_portile2 2.6.1
       Fetching crass 1.0.6
       Fetching rack 2.2.3
       Fetching nio4r 2.5.8
       Installing rack 2.2.3
       Installing crass 1.0.6
       Fetching websocket-extensions 0.1.5
       Installing racc 1.5.2 with native extensions
       Installing nio4r 2.5.8 with native extensions
       Installing websocket-extensions 0.1.5
       Fetching marcel 1.0.2
       Installing marcel 1.0.2
       Fetching mini_mime 1.1.1
       Fetching bcrypt 3.1.17
       Installing mini_mime 1.1.1
       Installing bcrypt 3.1.17 with native extensions
       Fetching msgpack 1.4.2
       Installing msgpack 1.4.2 with native extensions
       Using bundler 2.3.10
       Fetching coderay 1.1.3
       Installing coderay 1.1.3
       Using digest 3.1.0
       Fetching faraday-em_http 1.0.0
       Installing faraday-em_http 1.0.0
       Fetching faraday-em_synchrony 1.0.0
       Installing faraday-em_synchrony 1.0.0
       Fetching faraday-excon 1.1.0
       Installing faraday-excon 1.1.0
       Fetching faraday-httpclient 1.0.1
       Installing faraday-httpclient 1.0.1
       Fetching multipart-post 2.1.1
       Fetching faraday-net_http 1.0.1
       Installing multipart-post 2.1.1
       Installing faraday-net_http 1.0.1
       Fetching faraday-net_http_persistent 1.2.0
       Fetching faraday-patron 1.0.0
       Installing faraday-net_http_persistent 1.2.0
       Fetching faraday-rack 1.0.0
       Installing faraday-patron 1.0.0
       Fetching faraday-retry 1.0.3
       Installing faraday-rack 1.0.0
       Using ruby2_keywords 0.0.5
       Fetching ffi 1.15.4
       Installing faraday-retry 1.0.3
       Fetching hpricot 0.8.6
       Installing hpricot 0.8.6 with native extensions
       Installing ffi 1.15.4 with native extensions
       Fetching mini_magick 4.11.0
       Installing mini_magick 4.11.0
       Fetching jwt 2.3.0
       Installing jwt 2.3.0
       Fetching kaminari-core 1.2.2
       Installing kaminari-core 1.2.2
       Fetching matrix 0.4.2
       Installing matrix 0.4.2
       Fetching method_source 1.0.0
       Installing method_source 1.0.0
       Fetching multi_json 1.15.0
       Installing multi_json 1.15.0
       Fetching multi_xml 0.6.0
       Installing multi_xml 0.6.0
       Fetching timeout 0.3.0
       Installing timeout 0.3.0
       Fetching oauth 0.5.8
       Installing oauth 0.5.8
       Fetching pg 1.4.3
       Installing pg 1.4.3 with native extensions
       Fetching psych 3.3.3
       Installing psych 3.3.3 with native extensions
       Fetching thor 1.1.0
       Installing thor 1.1.0
       Fetching tilt 2.0.10
       Installing tilt 2.0.10
       Fetching temple 0.8.2
       Installing temple 0.8.2
       Fetching tzinfo 1.2.9
       Installing tzinfo 1.2.9
       Fetching i18n 1.8.10
       Installing i18n 1.8.10
       Fetching websocket-driver 0.7.5
       Installing websocket-driver 0.7.5 with native extensions
       Fetching rack-test 1.1.0
       Installing rack-test 1.1.0
       Fetching rack-proxy 0.7.0
       Installing rack-proxy 0.7.0
       Fetching sprockets 4.0.2
       Installing sprockets 4.0.2
       Fetching mail 2.7.1
       Installing mail 2.7.1
       Fetching nokogiri 1.12.5
       Installing nokogiri 1.12.5 with native extensions
       Fetching faraday-multipart 1.0.3
       Installing faraday-multipart 1.0.3
       Fetching puma 4.3.8
       Installing puma 4.3.8 with native extensions
       Fetching pry 0.14.1
       Installing pry 0.14.1
       Fetching net-protocol 0.1.3
       Installing net-protocol 0.1.3
       Fetching bootsnap 1.9.1
       Installing bootsnap 1.9.1 with native extensions
       Fetching slim 4.1.0
       Installing slim 4.1.0
       Fetching activesupport 6.0.4.1
       Installing activesupport 6.0.4.1
       Fetching ruby-vips 2.1.4
       Installing ruby-vips 2.1.4
       Fetching sassc 2.4.0
       Installing sassc 2.4.0 with native extensions
       Fetching faraday 1.10.0
       Installing faraday 1.10.0
       Fetching pry-rails 0.3.9
       Installing pry-rails 0.3.9
       Fetching net-smtp 0.3.1
       Installing net-smtp 0.3.1
       Fetching globalid 0.5.2
       Installing globalid 0.5.2
       Fetching activemodel 6.0.4.1
       Installing activemodel 6.0.4.1
       Fetching jbuilder 2.11.2
       Installing jbuilder 2.11.2
       Fetching image_processing 1.12.2
       Installing image_processing 1.12.2
       Fetching oauth2 1.4.9
       Installing oauth2 1.4.9
       Fetching activejob 6.0.4.1
       Installing activejob 6.0.4.1
       Fetching activerecord 6.0.4.1
       Installing activerecord 6.0.4.1
       Fetching sorcery 0.16.3
       Installing sorcery 0.16.3
       Fetching kaminari-activerecord 1.2.2
       Installing kaminari-activerecord 1.2.2
       Fetching ransack 2.4.1
       Installing ransack 2.4.1
       Fetching html2slim 0.2.0
       Installing html2slim 0.2.0
       Fetching rails-dom-testing 2.0.3
       Fetching loofah 2.12.0
       Installing loofah 2.12.0
       Installing rails-dom-testing 2.0.3
       Fetching rails-html-sanitizer 1.4.2
       Installing rails-html-sanitizer 1.4.2
       Fetching actionview 6.0.4.1
       Installing actionview 6.0.4.1
       Fetching actionpack 6.0.4.1
       Fetching kaminari-actionview 1.2.2
       Installing kaminari-actionview 1.2.2
       Fetching kaminari 1.2.2
       Installing actionpack 6.0.4.1
       Installing kaminari 1.2.2
       Fetching actionmailer 6.0.4.1
       Fetching activestorage 6.0.4.1
       Fetching actioncable 6.0.4.1
       Installing actionmailer 6.0.4.1
       Installing activestorage 6.0.4.1
       Installing actioncable 6.0.4.1
       Fetching railties 6.0.4.1
       Fetching sprockets-rails 3.2.2
       Fetching actionmailbox 6.0.4.1
       Installing railties 6.0.4.1
       Installing sprockets-rails 3.2.2
       Fetching actiontext 6.0.4.1
       Installing actionmailbox 6.0.4.1
       Installing actiontext 6.0.4.1
       Fetching rails 6.0.4.1
       Fetching rails-i18n 6.0.0
       Fetching slim-rails 3.3.0
       Installing rails 6.0.4.1
       Installing slim-rails 3.3.0
       Fetching webpacker 4.3.0
       Installing rails-i18n 6.0.0
       Installing webpacker 4.3.0
       Fetching sassc-rails 2.1.2
       Installing sassc-rails 2.1.2
       Fetching sass-rails 6.0.0
       Installing sass-rails 6.0.0
       Bundle complete! 32 Gemfile dependencies, 98 gems now installed.
       Gems in the groups 'development' and 'test' were not installed.
       Bundled gems are installed into `./vendor/bundle`
       Post-install message from sorcery:
       As of version 1.0 oauth/oauth2 won't be automatically bundled so you may need to add those dependencies to your Gemfile.
       You may need oauth2 if you use external providers such as any of these: https://github.com/Sorcery/sorcery/tree/master/lib/sorcery/providers
       Bundle completed (115.74s)
       Cleaning up the bundler cache.
-----> Installing node-v16.13.1-linux-x64
-----> Installing yarn-v1.22.17
-----> Detecting rake tasks
-----> Preparing app for Rails asset pipeline
       Running: rake assets:precompile
       Calling `DidYouMean::SPELL_CHECKERS.merge!(error_name => spell_checker)' has been deprecated. Please call `DidYouMean.correct_error(error_name, spell_checker)' instead.
       yarn install v1.22.17
       [1/4] Resolving packages...
       [2/4] Fetching packages...
       [3/4] Linking dependencies...
       warning " > webpack-dev-server@4.10.1" has unmet peer dependency "webpack@^4.37.0 || ^5.0.0".
       warning "webpack-dev-server > webpack-dev-middleware@5.3.3" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
       [4/4] Building fresh packages...
       error /tmp/build_fa395875/node_modules/node-sass: Command failed.    ①
       Exit code: 1
       Command: node scripts/build.js
       Arguments: 
       Directory: /tmp/build_fa395875/node_modules/node-sass
       Output:
       Building: /tmp/build_fa395875/bin/node /tmp/build_fa395875/node_modules/node-gyp/bin/node-gyp.js rebuild --verbose --libsass_ext= --libsass_cflags= --libsass_ldflags= --libsass_library=
       gyp info it worked if it ends with ok
       gyp verb cli [
       gyp verb cli   '/tmp/build_fa395875/bin/node',
       gyp verb cli   '/tmp/build_fa395875/node_modules/node-gyp/bin/node-gyp.js',
       gyp verb cli   'rebuild',
       gyp verb cli   '--verbose',
       gyp verb cli   '--libsass_ext=',
       gyp verb cli   '--libsass_cflags=',
       gyp verb cli   '--libsass_ldflags=',
       gyp verb cli   '--libsass_library='
       gyp verb cli ]
       gyp info using node-gyp@3.8.0
       gyp info using node@16.13.1 | linux | x64
       gyp verb command rebuild []
       gyp verb command clean []
       gyp verb clean removing "build" directory
       gyp verb command configure []
       gyp verb check python checking for Python executable "python2" in the PATH
       gyp verb `which` failed Error: not found: python2
       gyp verb `which` failed     at getNotFoundError (/tmp/build_fa395875/node_modules/which/which.js:13:12)
       gyp verb `which` failed     at F (/tmp/build_fa395875/node_modules/which/which.js:68:19)
       gyp verb `which` failed     at E (/tmp/build_fa395875/node_modules/which/which.js:80:29)
       gyp verb `which` failed     at /tmp/build_fa395875/node_modules/which/which.js:89:16
       gyp verb `which` failed     at /tmp/build_fa395875/node_modules/isexe/index.js:42:5
       gyp verb `which` failed     at /tmp/build_fa395875/node_modules/isexe/mode.js:8:5
       gyp verb `which` failed     at FSReqCallback.oncomplete (node:fs:198:21)
       gyp verb `which` failed  python2 Error: not found: python2
       gyp verb `which` failed     at getNotFoundError (/tmp/build_fa395875/node_modules/which/which.js:13:12)
       gyp verb `which` failed     at F (/tmp/build_fa395875/node_modules/which/which.js:68:19)
       gyp verb `which` failed     at E (/tmp/build_fa395875/node_modules/which/which.js:80:29)
       gyp verb `which` failed     at /tmp/build_fa395875/node_modules/which/which.js:89:16
       gyp verb `which` failed     at /tmp/build_fa395875/node_modules/isexe/index.js:42:5
       gyp verb `which` failed     at /tmp/build_fa395875/node_modules/isexe/mode.js:8:5
       gyp verb `which` failed     at FSReqCallback.oncomplete (node:fs:198:21) {
       gyp verb `which` failed   code: 'ENOENT'
       gyp verb `which` failed }
       gyp verb check python checking for Python executable "python" in the PATH
       gyp verb `which` succeeded python /usr/bin/python
       gyp ERR! configure error 
       gyp ERR! stack Error: Command failed: /usr/bin/python -c import sys; print "%s.%s.%s" % sys.version_info[:3];
       gyp ERR! stack   File "<string>", line 1
       gyp ERR! stack     import sys; print "%s.%s.%s" % sys.version_info[:3];
       gyp ERR! stack                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
       gyp ERR! stack SyntaxError: Missing parentheses in call to 'print'. Did you mean print(...)?
       gyp ERR! stack 
       gyp ERR! stack     at ChildProcess.exithandler (node:child_process:397:12)
       gyp ERR! stack     at ChildProcess.emit (node:events:390:28)
       gyp ERR! stack     at maybeClose (node:internal/child_process:1064:16)
       gyp ERR! stack     at Process.ChildProcess._handle.onexit (node:internal/child_process:301:5)
       gyp ERR! System Linux 4.4.0-1104-aws
       gyp ERR! command "/tmp/build_fa395875/bin/node" "/tmp/build_fa395875/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
       gyp ERR! cwd /tmp/build_fa395875/node_modules/node-sass
       gyp ERR! node -v v16.13.1
       gyp ERR! node-gyp -v v3.8.0
       gyp ERR! not ok 
       Build failed with error code: 1
       info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
 !
 !     Precompiling assets failed.
 !
 !     Push rejected, failed to compile Ruby app.
 !     Push failed

ログがすごい長いけど①が怪しい。。。
node-sassのコマンドが失敗したとのことで、これ関係のエラーをググってみると、nodeとnode-sassのバージョンの違いによるものとの事で、以下で解決できました。

①webpackerのバージョンアップ

- gem 'webpacker', '~> 4.0'
+ gem 'webpacker', '~> 5.0'

②yarn.lockの削除
ファイルを削除する

③package.jsonで以下のようにwebpackerのバージョンを指定

    "@rails/webpacker": "5.4.3",

④yarn installを実行

$ yarn install

⑤node-sassのバージョンをnode.jsに合わせる

$ yarn add node-sass

⑥再度デプロイ

$ git push heroku main

ポイント
・herokuにデプロイするとGemfile.lockBUNDLED WITHが削除されて、heroku指定のBundlerのバージョンが使われる。(自分でbundlerのバージョン指定はできない)
そのため、ローカル環境とheroku環境でbundlerのバージョンが異なるが、bundlerのバージョンの違いによる不具合は、基本的に起こらないとのこと。

・herokuのログは、以下のようにheroku画面でも確認できる
①以下のDashboardをクリック
Image from Gyazo


②以下のように対象のサービスをクリック
Image from Gyazo


③以下のOverviewをクリック
Image from Gyazo


④以下のLatest activityにログが記載されている
Image from Gyazo

参考記事

RailsをHerokuにデプロイするときのBundlerバージョン(2020年版)|TechRacho by BPS株式会社

【heroku】herokuにてデプロイエラー【The engine "node" is incompatible with this..】

rubocopの設定

rubocopの設定

rubocopの設定方法がイマイチ分からず調べたので、こちらに備忘録として残します。

rubocopでは、最初からLintチェックのレベルが設定されているが特定のファイルだけLintチェックを行わないようにしたい場合がある。(特定のファイルのみどうしてもLintチェックを通過するようにコードを書けない場合など。。)
そんな時に、そのファイルのみ特定のLintチェックをパスするようにする方法を以下に示します。

以下のように記載することで特定のLintチェックを指定したファイルでパスするようにできます。

[.rubocop.yml]

inherit_from: .rubocop_todo.yml

AllCops:
  TargetRubyVersion: 2.5
  # 除外
  Exclude:
    - 'bin/**'
    - 'lib/**'
    - 'db/migrate/*'
    - 'db/schema.rb'
    - 'config/puma.rb'
    - 'config/spring.rb'
    - 'config/application.rb'
    - 'config/environments/*'
    - 'config/initializers/*'
    - 'script/**/*'
    - 'node_modules/**/*'
    - Gemfile
    - 'vendor/**/*'
    - 'spec/**/*'


CyclomaticComplexity:   # ①
  Exclude:
    - 'app/forms/calculate_cooking_time.rb'

①を記載しないと以下のようになる。

 % rubocop
The following cops were added to RuboCop, but are not configured. Please set Enabled to either `true` or `false` in your `.rubocop.yml` file.

Please also note that you can opt-in to new cops by default by adding this to your config:
  AllCops:
    NewCops: enable

Gemspec/DateAssignment: # new in 1.10
  Enabled: true
Layout/LineEndStringConcatenationIndentation: # new in 1.18
  Enabled: true
Layout/SpaceBeforeBrackets: # new in 1.7
  Enabled: true
Lint/AmbiguousAssignment: # new in 1.7
  Enabled: true
Lint/AmbiguousOperatorPrecedence: # new in 1.21
  Enabled: true
Lint/AmbiguousRange: # new in 1.19
  Enabled: true
Lint/DeprecatedConstants: # new in 1.8
  Enabled: true
Lint/DuplicateBranch: # new in 1.3
  Enabled: true
Lint/DuplicateRegexpCharacterClassElement: # new in 1.1
  Enabled: true
Lint/EmptyBlock: # new in 1.1
  Enabled: true
Lint/EmptyClass: # new in 1.3
  Enabled: true
Lint/EmptyInPattern: # new in 1.16
  Enabled: true
Lint/IncompatibleIoSelectWithFiberScheduler: # new in 1.21
  Enabled: true
Lint/LambdaWithoutLiteralBlock: # new in 1.8
  Enabled: true
Lint/NoReturnInBeginEndBlocks: # new in 1.2
  Enabled: true
Lint/NumberedParameterAssignment: # new in 1.9
  Enabled: true
Lint/OrAssignmentToConstant: # new in 1.9
  Enabled: true
Lint/RedundantDirGlobSort: # new in 1.8
  Enabled: true
Lint/RequireRelativeSelfPath: # new in 1.22
  Enabled: true
Lint/SymbolConversion: # new in 1.9
  Enabled: true
Lint/ToEnumArguments: # new in 1.1
  Enabled: true
Lint/TripleQuotes: # new in 1.9
  Enabled: true
Lint/UnexpectedBlockArity: # new in 1.5
  Enabled: true
Lint/UnmodifiedReduceAccumulator: # new in 1.1
  Enabled: true
Security/IoMethods: # new in 1.22
  Enabled: true
Style/ArgumentsForwarding: # new in 1.1
  Enabled: true
Style/CollectionCompact: # new in 1.2
  Enabled: true
Style/DocumentDynamicEvalDefinition: # new in 1.1
  Enabled: true
Style/EndlessMethod: # new in 1.8
  Enabled: true
Style/HashConversion: # new in 1.10
  Enabled: true
Style/HashExcept: # new in 1.7
  Enabled: true
Style/IfWithBooleanLiteralBranches: # new in 1.9
  Enabled: true
Style/InPatternThen: # new in 1.16
  Enabled: true
Style/MultilineInPatternThen: # new in 1.16
  Enabled: true
Style/NegatedIfElseCondition: # new in 1.2
  Enabled: true
Style/NilLambda: # new in 1.3
  Enabled: true
Style/NumberedParameters: # new in 1.22
  Enabled: true
Style/NumberedParametersLimit: # new in 1.22
  Enabled: true
Style/QuotedSymbols: # new in 1.16
  Enabled: true
Style/RedundantArgument: # new in 1.4
  Enabled: true
Style/RedundantSelfAssignmentBranch: # new in 1.19
  Enabled: true
Style/SelectByRegexp: # new in 1.22
  Enabled: true
Style/StringChars: # new in 1.12
  Enabled: true
Style/SwapValues: # new in 1.1
  Enabled: true
For more information: https://docs.rubocop.org/rubocop/versioning.html
Inspecting 31 files
..........C....................

Offenses:

app/forms/calculate_cooking_time.rb:18:3: C: Metrics/PerceivedComplexity: Perceived complexity for  
 calculate_cooking_total_time is too high. [27/8]   ②
  def calculate_cooking_total_time ...
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

31 files inspected, 1 offense detected

Metrics/PerceivedComplexityのLintチェックに引っかかる。
②のMetrics/PerceivedComplexity.rubocop.ymlに記載して除外ファイルを設定することで、このファイルではMetrics/PerceivedComplexityのLintチェックが行われなくなる。

外部キーにnullを入れる方法

外部キーにnullを入れる方法

1対多の関係で、通常通り外部キーを持つレコードと外部キーを持たないレコードがある時に外部キーにnullを入れる方法を 備忘録としてこちらにまとめます。

以下のようなアソシエーション関係のモデルがあります。

[app/models/cookware.rb]

class Cookware < ApplicationRecord
  has_many :cooking_informations
end
[app/models/cook_information.rb]

class CookingInformation < ApplicationRecord
  belongs_to :cookware, optional: true
end

cook_informationのレコードには、外部キーのcookware_idが入るレコードと入らないレコードがあります。
そんな時は、optional: trueオプションを付与することで外部キーにnullを許容することができます。

参考記事

外部キーにnullが入ることを許容する[Rails] - Qiita

メーラーのRSpecテスト

メーラーRSpecテスト

メーラーRSpecテストでハマったことがあったので、備忘録としてこちらにまとめます。

コードは、以下のようになります。

[app/mailers/user_mailer.rb]

class UserMailer < ApplicationMailer

  # Subject can be set in your I18n file at config/locales/en.yml
  # with the following lookup:
  #
  #   en.user_mailer.reset_password_email.subject
  #
  def reset_password_email(user)
    @user = User.find user.id
    @url  = edit_password_reset_url(@user.reset_password_token)
    mail(:to => user.email,
         :subject => "パスワード再発行のお知らせ")
  end
end
[app/views/user_mailer/reset_password_email.html.slim]

doctype html
html
  head
    meta[content="text/html; charset=UTF-8" http-equiv="Content-Type"]
  body
    p = "#{@user.name} 様"
    
    p パスワード再発行の依頼を受け付けました。
    p こちらのリンクからパスワードの再発行を行ってください。
    p = link_to nil, @url
[app/views/user_mailer/reset_password_email.text.slim]

= "#{@user.name} 様"

パスワード再発行の依頼を受け付けました。
こちらのリンクからパスワードの再発行を行ってください。
= @url
[app/mailers/user_mailer_spec.rb]

require "rails_helper"

RSpec.describe UserMailer, type: :mailer do
  describe 'パスワードリセットのメール送信の検証' do
    let(:user) { create(:user) }
    let(:mail) { UserMailer.reset_password_email(user) }
    before do
      user.generate_reset_password_token!
      mail.deliver_now
    end
    
    context 'メールを送信した時' do
      it 'ヘッダー情報,ボディ情報が正しい' do
        expect(mail.subject).to eq 'パスワード再発行のお知らせ'
        expect(mail.to).to eq [user.email]
        expect(mail.from).to eq ['from@example.com']
      end

      it 'メール本文が正しい' do
        expect(mail.html_part.body.to_s).to have_content "#{user.name} 様"
        expect(mail.html_part.body.to_s).to have_content 'パスワード再発行の依頼を受け付けました。'
        expect(mail.html_part.body.to_s).to have_content 'こちらのリンクからパスワードの再発行を行ってください。'
        expect(mail.html_part.body.to_s).to have_content "http://localhost:3000/password_resets/#{user.reset_password_token}/edit"
        expect(mail.text_part.body.to_s).to have_content "#{user.name} 様"
        expect(mail.text_part.body.to_s).to have_content 'パスワード再発行の依頼を受け付けました。'
        expect(mail.text_part.body.to_s).to have_content 'こちらのリンクからパスワードの再発行を行ってください。'
        expect(mail.text_part.body.to_s).to have_content "http://localhost:3000/password_resets/#{user.reset_password_token}/edit"
      end
    end
  end
end

上記のテストを実行すると以下のようなエラーになります。

higmonta@higuchiyuunoMBP fishing_cooking % bundle exec rspec spec/mailers/user_mailer_spec.rb
DEPRECATION WARNING: Initialization autoloaded the constants ActionText::ContentHelper and ActionText::TagHelper.

Being able to do this is deprecated. Autoloading during initialization is going
to be an error condition in future versions of Rails.

Reloading does not reboot the application, and therefore code executed during
initialization does not run again. So, if you reload ActionText::ContentHelper, for example,
the expected changes won't be reflected in that stale Module object.

These autoloaded constants have been unloaded.

Please, check the "Autoloading and Reloading Constants" guide for solutions.
 (called from <top (required)> at /Users/higmonta/workspace/fishing_cooking/config/environment.rb:5)

UserMailer
  パスワードリセットのメール送信の検証
    メールを送信した時
      ヘッダー情報,ボディ情報が正しい
      メール本文が正しい (FAILED - 1)

Failures:

  1) UserMailer パスワードリセットのメール送信の検証 メールを送信した時 メール本文が正しい
     Failure/Error: expect(mail.text_part.body.to_s).to have_content 'パスワード再発行の依頼を受け付けました。'
       expected to find text "パスワード再発行の依頼を受け付けました。" in "大野 莉子 様。パスワード再発行の依頼を受け付けました>。こちらのリンクからパスワードの再発行を行ってください>http://localhost:3000/password_resets/hf6PPCGouyRVPfAzi3i3/edit"
     # ./spec/mailers/user_mailer_spec.rb:25:in `block (4 levels) in <top (required)>'

Finished in 0.36584 seconds (files took 3.99 seconds to load)
2 examples, 1 failure

Failed examples:

rspec ./spec/mailers/user_mailer_spec.rb:19 # UserMailer パスワードリセットのメール送信の検証 メールを送信した時 メール本文が正しい

デバッグして確認してみます。

higmonta@higuchiyuunoMBP fishing_cooking % bundle exec rspec spec/mailers/user_mailer_spec.rb
DEPRECATION WARNING: Initialization autoloaded the constants ActionText::ContentHelper and ActionText::TagHelper.

Being able to do this is deprecated. Autoloading during initialization is going
to be an error condition in future versions of Rails.

Reloading does not reboot the application, and therefore code executed during
initialization does not run again. So, if you reload ActionText::ContentHelper, for example,
the expected changes won't be reflected in that stale Module object.

These autoloaded constants have been unloaded.

Please, check the "Autoloading and Reloading Constants" guide for solutions.
 (called from <top (required)> at /Users/higmonta/workspace/fishing_cooking/config/environment.rb:5)

UserMailer
  パスワードリセットのメール送信の検証
    メールを送信した時
      ヘッダー情報,ボディ情報が正しい

^A^BFrom:^A^B /Users/higmonta/workspace/fishing_cooking/spec/mailers/user_mailer_spec.rb:24 :

    19:       it 'メール本文が正しい' do
    20:         expect(mail.html_part.body.to_s).to have_content "#{user.name} 様"
    21:         expect(mail.html_part.body.to_s).to have_content 'パスワード再発行の依頼を受け付けました。'
    22:         expect(mail.html_part.body.to_s).to have_content 'こちらのリンクからパスワードの再発行を行ってください。'
    23:         expect(mail.html_part.body.to_s).to have_content "http://localhost:3000/password_resets/#{user.reset_password_token}/edit"
 => 24:         binding.pry
    25:         expect(mail.text_part.body.to_s).to have_content "#{user.name} 様"
    26:         expect(mail.text_part.body.to_s).to have_content 'パスワード再発行の依頼を受け付けました。'
    27:         expect(mail.text_part.body.to_s).to have_content 'こちらのリンクからパスワードの再発行を行ってください。'
    28:         expect(mail.text_part.body.to_s).to have_content "http://localhost:3000/password_resets/#{user.reset_password_token}/edit"
    29:       end

[1] pry(#<RSpec::ExampleGroups::UserMailer::Nested::Nested>)> mail.html_part.body.to_s
=> "<!DOCTYPE html><html><head><meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\" /><style> /* Email styles need to be inline */ </style></head><body><!DOCTYPE html><html><head><meta content=\"text/html; charset=UTF-8\" http-equiv=\"Content-Type\" /></head><body><p>村上 美穂 様</p><p>パスワード再発行の依頼を受け付けました。</p><p>こちらのリンクからパスワードの再発行を行ってください。</p><p><a href=\"http://localhost:3000/password_resets/BtLzvHUukixrNqAQoJJx/edit\">http://localhost:3000/password_resets/BtLzvHUukixrNqAQoJJx/edit</a></p></body></html></body></html>"
[2] pry(#<RSpec::ExampleGroups::UserMailer::Nested::Nested>)> mail.text_part.body.to_s
=> "村上 美穂 様<パスワード再発行の依頼を受け付けました>。</パスワード再発行の依頼を受け付けました><こちらのリンクからパスワードの再発行を行ってください>。</こちらのリンクからパスワードの再発行を行ってください>http://localhost:3000/password_resets/BtLzvHUukixrNqAQoJJx/edit"
[3] pry(#<RSpec::ExampleGroups::UserMailer::Nested::Nested>)> expect(mail.text_part.body.to_s).to have_content "#{user.name} 様"
=> true
[4] pry(#<RSpec::ExampleGroups::UserMailer::Nested::Nested>)> expect(mail.text_part.body.to_s).to have_content 'パスワード再発行の依頼を受け付けました [4] pry(#<RSpec::ExampleGroups::UserMailer::Nested::Nested>)> expect(mail.text_part.body.to_s).to have_content 'パスワード再発行の依頼を受け付けました。'
RSpec::Expectations::ExpectationNotMetError: expected to find text "パスワード再発行の依頼を受け付けました。" in "村上 美穂 様。パスワード再発行の依頼を受け付けました>。こちらのリンクからパスワードの再発行を行ってください>http://localhost:3000/password_resets/BtLzvHUukixrNqAQoJJx/edit"
from /Users/higmonta/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rspec-support-3.11.0/lib/rspec/support.rb:102:in `block in <module:Support>'
[5] pry(#<RSpec::ExampleGroups::UserMailer::Nested::Nested>)> expect(mail.text_part.body.to_s).to have_content 'こちらのリンクからパスワードの再発行を [5] pry(#<RSpec::ExampleGroups::UserMailer::Nested::Nested>)> expect(mail.text_part.body.to_s).to have_content 'こちらのリンクからパスワードの再発行を行ってください。'
RSpec::Expectations::ExpectationNotMetError: expected to find text "こちらのリンクからパスワードの再発行を行ってください。" in "村上 美穂 様。パスワード再発行の依頼を受け付けました>。こちらのリンクからパスワードの再発行を行ってください>http://localhost:3000/password_resets/BtLzvHUukixrNqAQoJJx/edit"
from /Users/higmonta/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/rspec-support-3.11.0/lib/rspec/support.rb:102:in `block in <module:Support>'
[6] pry(#<RSpec::ExampleGroups::UserMailer::Nested::Nested>)> expect(mail.text_part.body.to_s).to have_content "http://localhost:3000/password_resets/#{user.reset_password_token}/edit"n}/edit"
=> true 

下記2つだけがエラーになっています。(ユーザー名の文章部分とURLの部分はエラーになっていません。)
expect(mail.text_part.body.to_s).to have_content 'パスワード再発行の依頼を受け付けました。'
expect(mail.text_part.body.to_s).to have_content 'こちらのリンクからパスワードの再発行を行ってください。'
下記のように期待している文章が入っているのでエラーにならないはずだが。。。。

[2] pry(#<RSpec::ExampleGroups::UserMailer::Nested::Nested>)> mail.text_part.body.to_s
=> "村上 美穂 様<パスワード再発行の依頼を受け付けました>。</パスワード再発行の依頼を受け付けました><こちらのリンクからパスワードの再発行を行ってください>。</こちらのリンクからパスワードの再発行を行ってください>http://localhost:3000/password_resets/BtLzvHUukixrNqAQoJJx/edit"

上記を確認するとエラーになっている文章の部分だけ<</>が入っており、これに問題がありそうと考えました。
そもそも、なぜここの文章だけが<</>が入っているのか再度メールのビューを確認しました。

[app/views/user_mailer/reset_password_email.text.slim]

= "#{@user.name} 様"

パスワード再発行の依頼を受け付けました。  ①
こちらのリンクからパスワードの再発行を行ってください。  ②
= @url

そもそもこれってslim形式→text形式に変換されるファイルなはずなのだが、①、②にhtmlタグを記載せずに文章だけ書いてしまっている。(textのように記載してしまっている。)
下記のように編集したところ、テストが通りました。

p = "#{@user.name} 様"

p パスワード再発行の依頼を受け付けました。
p こちらのリンクからパスワードの再発行を行ってください。
p = @url

デバッグで確認したら以下のようになり、<</>が無くなっていました。

higmonta@higuchiyuunoMBP fishing_cooking % bundle exec rspec spec/mailers/user_mailer_spec.rb
DEPRECATION WARNING: Initialization autoloaded the constants ActionText::ContentHelper and ActionText::TagHelper.

Being able to do this is deprecated. Autoloading during initialization is going
to be an error condition in future versions of Rails.

Reloading does not reboot the application, and therefore code executed during
initialization does not run again. So, if you reload ActionText::ContentHelper, for example,
the expected changes won't be reflected in that stale Module object.

These autoloaded constants have been unloaded.

Please, check the "Autoloading and Reloading Constants" guide for solutions.
 (called from <top (required)> at /Users/higmonta/workspace/fishing_cooking/config/environment.rb:5)

UserMailer
  パスワードリセットのメール送信の検証
    メールを送信した時
      ヘッダー情報,ボディ情報が正しい

^A^BFrom:^A^B /Users/higmonta/workspace/fishing_cooking/spec/mailers/user_mailer_spec.rb:24 :

    19:       it 'メール本文が正しい' do
    20:         expect(mail.html_part.body.to_s).to have_content "#{user.name} 様"
    21:         expect(mail.html_part.body.to_s).to have_content 'パスワード再発行の依頼を受け付けました。'
    22:         expect(mail.html_part.body.to_s).to have_content 'こちらのリンクからパスワードの再発行を行ってください。'
    23:         expect(mail.html_part.body.to_s).to have_content "http://localhost:3000/password_resets/#{user.reset_password_token}/edit"
 => 24:         binding.pry
    25:         expect(mail.text_part.body.to_s).to have_content "#{user.name} 様"
    26:         expect(mail.text_part.body.to_s).to have_content 'パスワード再発行の依頼を受け付けました。'
    27:         expect(mail.text_part.body.to_s).to have_content 'こちらのリンクからパスワードの再発行を行ってください。'
    28:         expect(mail.text_part.body.to_s).to have_content "http://localhost:3000/password_resets/#{user.reset_password_token}/edit"
    29:       end

[1] pry(#<RSpec::ExampleGroups::UserMailer::Nested::Nested>)> mail.text_part.body.to_s
=> "<p>酒井 仁 様</p><p>パスワード再発行の依頼を受け付けました。</p><p>こちらのリンクからパスワードの再発行を行ってください。</p><p>http://localhost:3000/password_resets/mwxXk4h9vCMZfHwvXnRz/edit</p>"
[2] pry(#<RSpec::ExampleGroups::UserMailer::Nested::Nested>)> expect(mail.text_part.body.to_s).to have_content "#{user.name} 様"ame} 様"
=> true 
[3] pry(#<RSpec::ExampleGroups::UserMailer::Nested::Nested>)> expect(mail.text_part.body.to_s).to have_content 'パスワード再発行の依頼を受け付けました [3] pry(#<RSpec::ExampleGroups::UserMailer::Nested::Nested>)> expect(mail.text_part.body.to_s).to have_content 'パスワード再発行の依頼を受け付けました。'
=> true
[4] pry(#<RSpec::ExampleGroups::UserMailer::Nested::Nested>)> expect(mail.text_part.body.to_s).to have_content 'こちらのリンクからパスワードの再発行を [4] pry(#<RSpec::ExampleGroups::UserMailer::Nested::Nested>)> expect(mail.text_part.body.to_s).to have_content 'こちらのリンクからパスワードの再発行を行ってください。'
=> true
[5] pry(#<RSpec::ExampleGroups::UserMailer::Nested::Nested>)> expect(mail.text_part.body.to_s).to have_content "http://localhost:3000/password_resets/#{user.reset_password_token}/edit"
=> true

※ポイント
mail.html_part.body.to_s:マルチパートメールにしている場合にhtml形式のメール本文の検証ができる。
mail.text_part.body.to_s:マルチパートメールにしている場合にtext形式のメール本文の検証ができる。

それぞれのメソッドがどのような動きになっているのか気になったので、デバッグして確認した結果が以下になります。

higmonta@higuchiyuunoMBP fishing_cooking % bundle exec rspec spec/mailers/user_mailer_spec.rb
DEPRECATION WARNING: Initialization autoloaded the constants ActionText::ContentHelper and ActionText::TagHelper.

Being able to do this is deprecated. Autoloading during initialization is going
to be an error condition in future versions of Rails.

Reloading does not reboot the application, and therefore code executed during
initialization does not run again. So, if you reload ActionText::ContentHelper, for example,
the expected changes won't be reflected in that stale Module object.

These autoloaded constants have been unloaded.

Please, check the "Autoloading and Reloading Constants" guide for solutions.
 (called from <top (required)> at /Users/higmonta/workspace/fishing_cooking/config/environment.rb:5)

UserMailer
  パスワードリセットのメール送信の検証
    メールを送信した時
      ヘッダー情報,ボディ情報が正しい

^A^BFrom:^A^B /Users/higmonta/workspace/fishing_cooking/spec/mailers/user_mailer_spec.rb:24 :

    19:       it 'メール本文が正しい' do
    20:         expect(mail.html_part.body.to_s).to have_content "#{user.name} 様"
    21:         expect(mail.html_part.body.to_s).to have_content 'パスワード再発行の依頼を受け付けました。'
    22:         expect(mail.html_part.body.to_s).to have_content 'こちらのリンクからパスワードの再発行を行ってください。'
    23:         expect(mail.html_part.body.to_s).to have_content "http://localhost:3000/password_resets/#{user.reset_password_token}/edit"
 => 24:         binding.pry
    25:         expect(mail.text_part.body.to_s).to have_content "#{user.name} 様"
    26:         expect(mail.text_part.body.to_s).to have_content 'パスワード再発行の依頼を受け付けました。'
    27:         expect(mail.text_part.body.to_s).to have_content 'こちらのリンクからパスワードの再発行を行ってください。'
    28:         expect(mail.text_part.body.to_s).to have_content "http://localhost:3000/password_resets/#{user.reset_password_token}/edit"
    29:       end

[1] pry(#<RSpec::ExampleGroups::UserMailer::Nested::Nested>)> mail
=> #<Mail::Message:70296108227480, Multipart: true, Headers: <Date: Sun, 11 Sep 2022 04:46:08 +0900>, <From: from@example.com>, <To: delmer_brekke@hudson-hilll.co>, <Message-ID: <631ce980c1322_1665e3fef12436e6c5881e@higuchiyuunoMBP.mail>>, <Subject: パスワード再発行のお知らせ>, <Mime-Version: 1.0>, <Content-Type: multipart/alternative; boundary="--==_mimepart_631ce980c0d0a_1665e3fef12436e6c5879e"; charset=UTF-8>, <Content-Transfer-Encoding: 7bit>>
[2] pry(#<RSpec::ExampleGroups::UserMailer::Nested::Nested>)> mail.html_part
=> #<Mail::Part:70296108194240, Multipart: false, Headers: <Content-Type: text/html>, <Content-Transfer-Encoding: base64>>
[3] pry(#<RSpec::ExampleGroups::UserMailer::Nested::Nested>)> mail.html_part.body
=> #<Mail::Body:0x00007fde2d1d1f88
 @ascii_only=false,
 @boundary=nil,
 @charset=nil,
 @encoding="8bit",
 @epilogue=nil,
 @part_sort_order=["text/plain", "text/enriched", "text/html"],
 @parts=[],
 @preamble=nil,
 @raw_source=
  "<!DOCTYPE html><html><head><meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\" /><style> /* Email styles need to be inline */ </style></head><body><!DOCTYPE html><html><head><meta content=\"text/html; charset=UTF-8\" http-equiv=\"Content-Type\" /></head><body><p>千葉 一輝 様</p><p>パスワード再発行の依頼を受け付けました。</p><p>こちらのリンクからパスワードの再発行を行ってください。</p><p><a href=\"http://localhost:3000/password_resets/xyD6ASVsM1w6G-gXedCS/edit\">http://localhost:3000/password_resets/xyD6ASVsM1w6G-gXedCS/edit</a></p></body></html></body></html>">
[4] pry(#<RSpec::ExampleGroups::UserMailer::Nested::Nested>)> mail.html_part.body.to_s
=> "<!DOCTYPE html><html><head><meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\" /><style> /* Email styles need to be inline */ </style></head><body><!DOCTYPE html><html><head><meta content=\"text/html; charset=UTF-8\" http-equiv=\"Content-Type\" /></head><body><p>千葉 一輝 様</p><p>パスワード再発行の依頼を受け付けました。</p><p>こちらのリンクからパスワードの再発行を行ってください。</p><p><a href=\"http://localhost:3000/password_resets/xyD6ASVsM1w6G-gXedCS/edit\">http://localhost:3000/password_resets/xyD6ASVsM1w6G-gXedCS/edit</a></p></body></html></body></html>"
[5] pry(#<RSpec::ExampleGroups::UserMailer::Nested::Nested>)> mail.text_part
=> #<Mail::Part:70296108178900, Multipart: false, Headers: <Content-Type: text/plain>, <Content-Transfer-Encoding: base64>>
[6] pry(#<RSpec::ExampleGroups::UserMailer::Nested::Nested>)> mail.text_part.body
=> #<Mail::Body:0x00007fde2d1d0f70
 @ascii_only=false,
 @boundary=nil,
 @charset=nil,
 @encoding="8bit",
 @epilogue=nil,
 @part_sort_order=["text/plain", "text/enriched", "text/html"],
 @parts=[],
 @preamble=nil,
 @raw_source=
  "千葉 一輝 様<パスワード再発行の依頼を受け付けました>。</パスワード再発行の依頼を受け付けました><こちらのリンクからパスワードの再発行を行ってください>。</こちらのリンクからパスワードの再発行を行ってください>http://localhost:3000/password_resets/xyD6ASVsM1w6G-gXedCS/edit">
[7] pry(#<RSpec::ExampleGroups::UserMailer::Nested::Nested>)> mail.text_part.body.to_s
=> "千葉 一輝 様<パスワード再発行の依頼を受け付けました>。</パスワード再発行の依頼を受け付けました><こちらのリンクからパスワードの再発行を行ってください>。</こちらのリンクからパスワードの再発行を行ってください>http://localhost:3000/password_resets/xyD6ASVsM1w6G-gXedCS/edit"

参考記事

RSpecでメーラーのテスト実行時にメールの本文がなぜか空になっている問題を解決する - Qiita

rspec2 - rspec-email - How to get the body text? - Stack Overflow

Rails / Ruby : Mail の HTML テキスト を取得する方法 - Qiita

【rails】【rspec】RspecでRails のActionMailer の本文をテストする - Qiita

ビューファイル毎に読み込ませるjsファイルを変えたい

ビューファイル毎に読み込ませるjsファイルを変えたい

ビューファイル毎に読み込ませるjsファイルを分ける方法を自分の備忘録として、こちらにまとめます。
Railsでは、アセットパイプラインによりマニフェストファイルからアセット(CSSファイルやJSファイル)をまとめて読み込み、アセットをまとめて読み込んでいるマニフェストファイルをレイアウトファイルで読み込んでいるというロジックになっている為、特定のページでのみで使用するjsファイルも違うページで読み込んでしまい存在しないDOMに対してaddEventListenerなどが実行されてしまい開発者ツール上で以下のようなエラーになってしまう。

Image from Gyazo

これの解決方法としては、ビュー毎に読み込むjsファイルを分ければ良い。
方法は、以下のようになります。

現時点では、以下のようになっています。
app/javascriptsフォルダ以下にそれぞれの機能毎のjsファイルが以下のように存在します。

Image from Gyazo

上記の機能毎のjsファイルを以下のようにマニフェストファイルで読み込んでいる。

[app/javascript/packs/application.js]

// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.

require('jquery')
require("@rails/ujs").start()
require("@rails/activestorage").start()
require("channels")
require('bootstrap')

import 'bootstrap';
import '@fortawesome/fontawesome-free/js/all';
import '../javascripts/search_cooking_select_box';       # ここで読み込んでいる
import '../javascripts/search_calculate_cooking_time_select_box';       # ここで読み込んでいる
import '../javascripts/search_cooking_memory';           # ここで読み込んでいる
import '../javascripts/image_preview';             # ここで読み込んでいる
window.$ = $;
// Uncomment to copy all static images under ../images to the output folder and reference
// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)
// or the `imagePath` JavaScript helper below.
//
// const images = require.context('../images', true)
// const imagePath = (name) => images(name, true)

上記のマニフェストファイルを以下のようにレイアウトファイルで読み込んでいる。

[app/views/layouts/application.html.slim]

doctype html
html
  head
    title = page_full_title(yield(:title))
    = csrf_meta_tags
    = csp_meta_tag
    = stylesheet_link_tag 'application', media: 'all'        ここでCSSのマニフェストファイルを読み込んでいる
    = javascript_pack_tag 'application'       ここでJava Scriptのマニフェストファイルを読み込んでいる
  body
    - if logged_in?
      = render partial: 'shared/after_login_header'
    - else
      = render partial: 'shared/before_login_header'
    = render partial: 'shared/flash_message'
    = yield

このような過程で全てのビューファイルで全てのjsファイルが読み込まれてしまっている為、以下のように変更する。

まず以下のようにマニフェストファイルから特定のビューでしか使用しないjsファイルを削除する。

[app/javascript/packs/application.js]

// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.

require('jquery')
require("@rails/ujs").start()
require("@rails/activestorage").start()
require("channels")
require('bootstrap')

import 'bootstrap';
import '@fortawesome/fontawesome-free/js/all';
# ここで読み込んでいたビュー毎のjsファイルを削除

window.$ = $;
// Uncomment to copy all static images under ../images to the output folder and reference
// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)
// or the `imagePath` JavaScript helper below.
//
// const images = require.context('../images', true)
// const imagePath = (name) => images(name, true)

レイアウトファイル(app/views/layouts/application.html.slim)からは、そのままマニフェストファイルを読み込むようにする。

[app/javascript/packs]フォルダ以下に以下のように自分でマニフェストファイルを作成する。

Image from Gyazo

以下のように作成したマニフェストファイルからビュー毎に使用するjsファイルを読み込む。

[app/javascript/packs/image_preview.js]

import '../javascripts/image_preview';
[app/javascript/packs/search_calculate_cooking_time_select_box.js]

import '../javascripts/search_calculate_cooking_time_select_box';
[app/javascript/packs/search_cooking_memory.js]

import '../javascripts/search_cooking_memory';
[app/javascript/packs/search_cooking_select_box.js]

import '../javascripts/search_cooking_select_box';

※読み込むjsファイルは相対パスで記載する必要がある。

上記のようなマニフェストファイルを以下のようにjsを使用するビューファイル毎で直接読み込むようにする。

[app/views/cooking_informations/index.html.slim]

= javascript_pack_tag 'search_cooking_select_box'
= content_for(:title, (t '.title'))
.search-wrapper
  .container
    .row.justify-content-md-center
      .col-md-10
        = search_form_for @q, url: cooking_informations_path do |f|
          .mt-4
            = f.collection_select :fish_kind_eq, @fishes, :kind, :kind, { include_blank: "#{t 'defaults.search_for_fish'}" }, {class: 'search-select-form'}
            = f.collection_select :handle_pattern_eq, @handles, :pattern, :pattern, { include_blank: "#{t 'defaults.search_for_fish'}" }, {class: 'search-select-form'}
            = button_tag type: 'submit', class: 'btn btn-primary search-button' do
              i.fas.fa-search
    = render @cooking_informations
    = paginate @cooking_informations

これで使用するビューファイルだけでjsファイルを読み込むようになるため、開発者ツールでもエラーにならなくなる。

Image from Gyazo

参考記事

webpacker でページごとにスタイルを分ける - Qiita

WebpackerでJavaScriptを使ってハマった話 - sasaboの生活

Webpacker::Manifest::MissingEntryErrorの対処法 | ゆみしん夫婦のブログ

Railsで特定のページのみJavaScriptを読み込む方法を現役エンジニアが解説【初心者向け】 | TechAcademyマガジン

Rails6で、アプリの特定のビューでJavaScriptを動かす。 : リア充キラキラ系のnoteです。@kuromitsu_ka

javascript — ビューごとのJavaScriptファイルRails

http://www.code-magagine.com/?p=4609

Railsでページごとのscssを管理する方法 -- blog.10rane.com

Ruby on Rails のアセットパイプラインの挙動を環境ごとに学ぶ - 30歳からのプログラミング

RailsでcssファイルとJavascriptファイルをマニフェストファイルから読み込む | Boys Be Engineer 非エンジニアよ、エンジニアになれ

Railsのマニフェストファイルを使ったJsとStylesheetの呼び出し - Qiita

RSpecでセレクトボックスの選択文字を出力する方法

RSpecでセレクトボックスの選択文字を出力する方法

RSpecでセレクトボックスの選択文字を出力する方法を自分の備忘録としてこちらにまとめます。

以下のようなセレクトボックスがあります。

<select class="search-select-form" name="q[fish_kind_eq]" id="q_fish_kind_eq">
  <option value="">魚の種類(必須)</option>
  <option value="アジ">アジ</option>
  <option value="マメアジ">マメアジ</option>
  <option value="イカ">イカ</option>
  <option value="サバ">サバ</option>
  <option value="マハゼ">マハゼ</option>
  <option value="カサゴ">カサゴ</option>
  <option value="タチウオ">タチウオ</option>
  <option value="カワハギ">カワハギ</option>
  <option value="イシモチ">イシモチ</option>
  <option value="メジナ">メジナ</option>
  <option value="タコ">タコ</option>
</select>

この時にセレクトボックスの中にある選択肢は、以下のようにして取り出せます。

[1] pry(#<RSpec::ExampleGroups::SearchCookings::Nested::Nested::Nested_4>)> within('#q_fish_kind_eq') do
[1] pry(#<RSpec::ExampleGroups::SearchCookings::Nested::Nested::Nested_4>)*   texts = all('option').map(&:text)
[1] pry(#<RSpec::ExampleGroups::SearchCookings::Nested::Nested::Nested_4>)* end  
=> ["魚の種類(必須)", "アジ", "マメアジ", "イカ", "サバ", "マハゼ", "カサゴ", "タチウオ", "カワハギ", "イシモチ", "メジナ", "タコ"]

上記のイメージは、以下のようになる。
within('#q_fish_kind_eq') do〜endで範囲を指定する。

all('option')で全てのoption要素を取得して、mapメソッドにtextメソッドを引数で渡すことにより選択肢の中身が配列として取得できる。
※ textメソッドの動きは、以下のようになる。

[1] pry(#<RSpec::ExampleGroups::SearchCookings::Nested::Nested::Nested_4>)> all('option').first        #全てのoption要素を取得
=> #<Capybara::Node::Element tag="option" path="/HTML/BODY[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/FORM[1]/DIV[1]/SELECT[1]/OPTION[1]">
[1] pry(#<RSpec::ExampleGroups::SearchCookings::Nested::Nested::Nested_4>)> all('option').first.text     #全てのoption要素の内1番最初のものを取得して、それにtextメソッドを実行
=> "魚の種類(必須)"

mapメソッドの動きは、以下のようになる。(ブロック内の処理をした新しい配列が取得できる)

[1] pry(main)> a = ['a', 'b', 'c', 'd'].map do |f|
[1] pry(main)*   f.upcase
[1] pry(main)* end  
=> ["A", "B", "C", "D"]
[2] pry(main)> a
=> ["A", "B", "C", "D"]

参考記事

Capybaraでセレクトボックスのoptionの内容だけを取得するにはどうすればよいでしょうか?