気ままに気ままのエンジニアブログ

定期的に得た知見を気ままに発信中

【Rails/enum】ArgumentError ('0' is not a valid section):エラーの解決方法

こんにちは。

気がついたら記念すべき50投稿目の記事でした。
誰かのソリューションになってれば嬉しい!そんなことを思った寒い日の夜。

どうもハチマキです。

はじめに

今回は、formでselectできるようにするため、enumを定義しました。
その際に発生したArgumentError ('0' is not a valid section):のエラー解決方法ついて書いていきたいと思います。

では早速行きましょう!

本日の概要 : ArgumentError ('0' is not a valid section):エラーの解決方法

事前情報

今回はこのようなテーブルを使っていきます。

create_table "schedule_results", force: :cascade do |t|
    t.datetime "match_date_time"
    t.integer "section"
    t.integer "opponent"
    t.integer "match_result"
    t.integer "stadium"
    t.integer "home_and_away"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

事象

対象のカラムをintegerにして、準備万端!いざformを投稿したらArgumentError ('0' is not a valid section):エラーが発生・・

エラー例

ターミナル

ArgumentError ('0' is not a valid section):
  
app/controllers/match/schedule_results_controller.rb:11:in `create'
Started POST "/match/schedule_results" for 127.0.0.1 at 2020-10-27 20:29:08 +0900
Processing by Match::ScheduleResultsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"69buIqkOJunb1OBSSv9CSaePvK5EnZmxLJ6JVpY1THE3hiqB/j/KPYxiPK51/kZcaCT2IZJ6xQ2YN87oZZgsVQ==", "schedule_result"=>{"match_date_time"=>"2020-10-28", "section"=>"0", "opponent"=>"1", "match_result"=>"", "stadium"=>"0", "home_and_away"=>"0"}, "commit"=>"スケジュールを投稿する"}
Completed 500 Internal Server Error in 2ms (ActiveRecord: 0.0ms)

原因予測

ArgumentError。。。
つまり、引数が正しくない時や足りない時に発生するエラーなので、返ってきた値のどこかに問題がありそうやなぁ🤔

原因

結論!こいつです。

{"match_date_time"=>"2020-10-28", "section"=>"0", "opponent"=>"1", "match_result"=>"", "stadium"=>"0", "home_and_away"=>"0"}, "commit"=>"スケジュールを投稿する"}

整数で返ってきてるのに!と思ったら'' "(ダブルクォーテーション)で囲われており、文字列で返ってきていたことが原因でエラーが発生してました。(デフォルトで" "で囲われてるみたいです)

解決方法

formでenumを定義してる箇所に「.keys」を定義してあげることでint型としてカラムに保存され、解決に至りました。

new.htm.haml

%div.form-group
    = f.label :section, ''
    = f.select :section, ScheduleResult.sections.keys, class: 'form-control'
%div.form-group
    = f.label :opponent, '対戦チーム'
    = f.select :opponent, ScheduleResult.opponents.keys, class: 'form-control'

= f.submit '登録する', class: 'btn btn-info btn-block'

ターミナル

Started POST "/match/schedule_results" for 127.0.0.1 at 2020-10-27 20:29:15 +0900
Processing by Match::ScheduleResultsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"kZ/htn7HyKQ0ttR/dNd0NSxtUGdQyGuXkc3pt6XSbxkj/sxCllMi4012QbZwMXd+s76fIy42FfCeSBo4J8fLNg==", "schedule_result"=>{"match_date_time"=>"2020-10-29", "section"=>"第1節", "opponent"=>"リューレント", "match_result"=>"", "stadium"=>"古々崎第1G", "home_and_away"=>"ホーム"}, "commit"=>"スケジュールを投稿する"}
   (0.1ms)  begin transaction
  ↳ app/controllers/match/schedule_results_controller.rb:11
  ScheduleResult Create (0.8ms)  INSERT INTO "schedule_results" ("match_date_time", "section", "opponent", "stadium", "home_and_away", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?)  [["match_date_time", "2020-10-29 00:00:00"], ["section", 0], ["opponent", 0], ["stadium", 0], ["home_and_away", 0], ["created_at", "2020-10-27 11:29:15.309864"], ["updated_at", "2020-10-27 11:29:15.309864"]]
  ↳ app/controllers/match/schedule_results_controller.rb:11
   (2.8ms)  commit transaction
  ↳ app/controllers/match/schedule_results_controller.rb:11
   (0.1ms)  begin transaction
  ↳ app/controllers/match/schedule_results_controller.rb:12
   (0.1ms)  commit transaction
  ↳ app/controllers/match/schedule_results_controller.rb:12
Redirected to http://0.0.0.0:3000/match/schedule_results/new
Completed 302 Found in 9ms (ActiveRecord: 3.9ms)

int型でDBに保存されました!解決解決っと。

補足

文字列でカラムに保存することも可能ですが、あまりよろしくないみたいです。
▽ご参考までにコード例

Started POST "/match/schedule_results" for 127.0.0.1 at 2020-10-28 08:01:57 +0900
Processing by Match::ScheduleResultsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"LBP7lJ0k3LiS2123eLG7rfIE6CY5ORoaROaX8q7o6M/wQz83yhUwbMVtgUtHsL+4Pa+iqe/eRqbwT9BMXUWI6w==", "schedule_result"=>{"match_date_time"=>"2020-10-14", "section"=>"第1節", "opponent"=>"", "match_result"=>"", "stadium"=>"古々崎第1G", "home_and_away"=>"ホーム"}, "commit"=>"スケジュールを投稿する"}
   (0.1ms)  begin transaction
  ↳ app/controllers/match/schedule_results_controller.rb:11
  ScheduleResult Create (1.1ms)  INSERT INTO "schedule_results" ("match_date_time", "section", "opponent", "stadium", "home_and_away", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?)  [["match_date_time", "2020-10-14 00:00:00"], ["section", "第1節"], ["opponent", ""], ["stadium", "古々崎第1G"], ["home_and_away", "ホーム"], ["created_at", "2020-10-27 23:01:57.699941"], ["updated_at", "2020-10-27 23:01:57.699941"]]
  ↳ app/controllers/match/schedule_results_controller.rb:11
   (4.0ms)  commit transaction
  ↳ app/controllers/match/schedule_results_controller.rb:11
   (0.1ms)  begin transaction
  ↳ app/controllers/match/schedule_results_controller.rb:12
   (0.0ms)  commit transaction
  ↳ app/controllers/match/schedule_results_controller.rb:12
Redirected to http://0.0.0.0:3000/match/schedule_results/new
Completed 302 Found in 12ms (ActiveRecord: 5.3ms)

【heroku/Rails】「You might need to specify "USING opponent::integer"」エラー。カラムを変更するだけでは解決できなかった話

こんにちは。

もうすぐクリスマス。今年もウキウキしたいと思います。

どうもハチマキです。

はじめに

このエラーの解決方法はいくつかググるとヒットしましたが、それらでは解決できず、解決するのに結局数日を費やしました。。辛かった。。
同じ境地に立っている方々のソリューションになれば幸いです。

では早速行きましょう!

本日の概要 : You might need to specify "USING opponent::integer"の解決方法

事前情報

今回はこのようなテーブルを使っていきます(modelにenumを定義し、整数管理をしてます)

create_table "schedule_results", force: :cascade do |t|
    t.datetime "match_date_time"
    t.integer "section", null: false
    t.integer "opponent", null: false
    t.integer "match_result"
    t.integer "stadium", null: false
    t.integer "home_and_away", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

事象

herokuにデプロイするために、$ git push heroku masterを実行し、いざ!$ heroku run rails db:migrateを実行したら下記エラーが発生。

エラー例

$ heroku run rails db:migrate

Running rails db:migrate on ⬢ アプリ名... up, run.2812 (Free)
D, [2020-11-04T01:03:12.699380 #4] DEBUG -- :    (12.7ms)  CREATE TABLE "schema_migrations" ("version" character varying NOT NULL PRIMARY KEY)
D, [2020-11-04T01:03:12.710028 #4] DEBUG -- :    (7.1ms)  CREATE TABLE "ar_internal_metadata" ("key" character varying NOT NULL PRIMARY KEY, "value" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
D, [2020-11-04T01:03:12.712139 #4] DEBUG -- :    (0.9ms)  SELECT pg_try_advisory_lock(5119105135108451025)
D, [2020-11-04T01:03:12.729785 #4] DEBUG -- :    (1.1ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
I, [2020-11-04T01:03:12.731636 #4]  INFO -- : Migrating to CreateScheduleResults (20201026011945)
D, [2020-11-04T01:03:12.735697 #4] DEBUG -- :    (0.8ms)  BEGIN
== 20201026011945 CreateScheduleResults: migrating ============================
-- create_table(:schedule_results)
D, [2020-11-04T01:03:12.743729 #4] DEBUG -- :    (7.1ms)  CREATE TABLE "schedule_results" ("id" bigserial primary key, "match_date_time" timestamp, "section" integer, "opponent" character varying, "match_result" character varying, "stadium" character varying, "home_and_away" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
   -> 0.0079s
== 20201026011945 CreateScheduleResults: migrated (0.0080s) ===================

D, [2020-11-04T01:03:12.749135 #4] DEBUG -- :   ActiveRecord::SchemaMigration Create (0.9ms)  INSERT INTO "schema_migrations" ("version") VALUES ($1) RETURNING "version"  [["version", "20201026011945"]]
D, [2020-11-04T01:03:12.751863 #4] DEBUG -- :    (2.4ms)  COMMIT
I, [2020-11-04T01:03:12.751984 #4]  INFO -- : Migrating to ChangeDatatypeOpponentOfScheduleResults (20201027022232)
D, [2020-11-04T01:03:12.753420 #4] DEBUG -- :    (0.7ms)  BEGIN
== 20201027022232 ChangeDatatypeOpponentOfScheduleResults: migrating ==========
-- change_column(:schedule_results, :opponent, :integer)
D, [2020-11-04T01:03:12.755207 #4] DEBUG -- :    (1.4ms)  ALTER TABLE "schedule_results" ALTER COLUMN "opponent" TYPE integer
D, [2020-11-04T01:03:12.756104 #4] DEBUG -- :    (0.7ms)  ROLLBACK
D, [2020-11-04T01:03:12.757154 #4] DEBUG -- :    (0.8ms)  SELECT pg_advisory_unlock(5119105135108451025)
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::DatatypeMismatch: ERROR:  column "opponent" cannot be cast automatically to type integer
HINT:  You might need to specify "USING opponent::integer".

エラー文を読んでいくと、
PG::DatatypeMismatch: ERROR: column "opponent" cannot be cast automatically to type integer
HINT: You might need to specify "USING opponent::integer".

つまり「opponentカラムを"USING opponent::integer"」に指定する必要があるとのことです。
なので、言われた通りマイグレーションファイルを作成しopponentカラムを"USING opponent::integer"に定義し直しました。

が、、、、、
変更後に再度$ git push heroku master、$ heroku run rails db:migrateを実行したら同じエラーが発生しました。。
このエラーを解決する記事は、どれもこれもエラーに出ているカラムを"USING opponent::integer"に変更すれば良い!という解決方法が多々ありましたが、それでは解決できませんでした。。

ここで数日こちらのエラー様と向き合い続けました。

原因の推測

なぜ"USING opponent::integer"を定義し直したのに同じエラーが発生するのか。。

・原因1:うまくカラムに"USING opponent::integer"が反映されていない?
・原因2:解決策がそもそも"USING opponent::integer"を定義することじゃない?
・原因3:SQLiteじゃ$ heroku run rails db:migrateできないの?
などなど、ググりながら推測してました。

原因はこれ!

結論!
すでに存在していたマイグレーションファイルが読み込まれ、本来integerで保存されるのに"opponent" character varyingになっていたことが原因でした。

よって、$ heroku run rails db:migrateを実行しても、新たに変更を加えたマイグレーションファイルではなかったため、$ heroku run rails db:migrateしてもherokuで作成されるDBに反映されてなかったということでした。

つまり"USING opponent::integer"にカラムを変更しなくてもデータ型をintegerにしていれば解決できるエラーでした。

$ heroku run rails db:migrate

・
・
・
== 20201026011945 CreateScheduleResults: migrating ============================
-- create_table(:schedule_results)
D, [2020-11-04T01:03:12.743729 #4] DEBUG -- :    (7.1ms)  CREATE TABLE "schedule_results" ("id" bigserial primary key, "match_date_time" timestamp, "section" integer, "opponent" character varying, ←ここ!!!
"match_result" character varying, "stadium" character varying, "home_and_away" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
   -> 0.0079s
== 20201026011945 CreateScheduleResults: migrated (0.0080s) =================== 
・
・
・

解決方法

私の対応としては、アプリケーションを作りたてだったこともあり、一度テーブルと既存のマイグレーションファイルを全て削除し、opponentカラムを等を"integer"に定義し直したテーブルを再度作成し、解決に至りました。

def change
    create_table :schedule_results do |t|
      t.datetime :match_date_time
      t.integer :section, null: false
      t.integer :opponent, null: false
      t.integer :match_result, default: ""
      t.integer :stadium, null: false
      t.integer :home_and_away, null: false

      t.timestamps

    end

再度$ git push heroku masterを実行し、一度$ heroku run rails db:resetでherokuの既存レコードを全て削除してから、

$ heroku run rails db:migrate

Running rails db:migrate on ⬢アプリ名... up, run.3410 (Free)

D, [2020-11-04T01:49:45.407343 #4] DEBUG -- :    (695.6ms)  CREATE TABLE "schema_migrations" ("version" character varying NOT NULL PRIMARY KEY)
D, [2020-11-04T01:49:45.505564 #4] DEBUG -- :    (95.2ms)  CREATE TABLE "ar_internal_metadata" ("key" character varying NOT NULL PRIMARY KEY, "value" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
D, [2020-11-04T01:49:45.507839 #4] DEBUG -- :    (0.9ms)  SELECT pg_try_advisory_lock(5119105135108451025)
D, [2020-11-04T01:49:45.761253 #4] DEBUG -- :    (1.0ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
I, [2020-11-04T01:49:45.762651 #4]  INFO -- : Migrating to CreateScheduleResults (20201104014024)
D, [2020-11-04T01:49:45.765550 #4] DEBUG -- :    (0.7ms)  BEGIN
== 20201104014024 CreateScheduleResults: migrating ============================
-- create_table(:schedule_results)
D, [2020-11-04T01:49:45.818313 #4] DEBUG -- :    (51.2ms)  CREATE TABLE "schedule_results" ("id" bigserial primary key, "match_date_time" timestamp, "section" integer NOT NULL, "opponent" integer NOT NULL, "match_result" integer DEFAULT NULL, "stadium" integer NOT NULL, "home_and_away" integer NOT NULL, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
   -> 0.0527s
== 20201104014024 CreateScheduleResults: migrated (0.0528s) ===================

D, [2020-11-04T01:49:45.822740 #4] DEBUG -- :   ActiveRecord::SchemaMigration Create (0.9ms)  INSERT INTO "schema_migrations" ("version") VALUES ($1) RETURNING "version"  [["version", "20201104014024"]]
D, [2020-11-04T01:49:45.824364 #4] DEBUG -- :    (1.4ms)  COMMIT
D, [2020-11-04T01:49:45.831674 #4] DEBUG -- :   ActiveRecord::InternalMetadata Load (1.8ms)  SELECT  "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2  [["key", "environment"], ["LIMIT", 1]]
D, [2020-11-04T01:49:45.838134 #4] DEBUG -- :    (0.7ms)  BEGIN
D, [2020-11-04T01:49:45.840383 #4] DEBUG -- :   ActiveRecord::InternalMetadata Create (0.9ms)  INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key"  [["key", "environment"], ["value", "production"], ["created_at", "2020-11-04 01:49:45.838415"], ["updated_at", "2020-11-04 01:49:45.838415"]]
D, [2020-11-04T01:49:45.842165 #4] DEBUG -- :    (1.6ms)  COMMIT
D, [2020-11-04T01:49:45.844081 #4] DEBUG -- :    (1.8ms)  SELECT pg_advisory_unlock(5119105135108451025)

ちゃんと新たに作成したマイグレーションファイルでDBcreateされました!やっと正常に動き出しました!!
ここまで長かったぁ。。。お疲れ様でした。

【Rspec/エラー】Unable to find Mozilla geckodriver.の解決方法

こんにちは。

最近間食が増えました。

どうもハチマキです。

はじめに

Rspecテスト時に発生したこのエラー。結構ググりましたが、なかなか解決できず苦戦しました。
今回はその解消方法について書いていこうと思います。

では早速行きましょう!

本日の概要 : Unable to find Mozilla geckodriver.の解決方法

事象

featureテストを実行した時に発生。。全然解決方法わからん。。

エラー例

$ bundle exec rspec spec/features/~~.rb 
Capybara starting Puma...
* Version 3.12.6 , codename: Llamas in Pajamas
* Min threads: 0, max threads: 4
* Listening on tcp://127.0.0.1:50950
F

Failures:

  1) ~~できること
     Failure/Error: visit root_path
     
     Selenium::WebDriver::Error::WebDriverError:
        Unable to find Mozilla geckodriver. Please download the server from https://github.com/mozilla/geckodriver/releases and place it somewhere on your PATH. More info at https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/WebDriver.
     # ./spec/features/~~.rb :6:in `block (3 levels) in <top (required)>'

Finished in 0.40453 seconds (files took 3.64 seconds to load)
1 example, 1 failure

原因

エラー内容にも記載してあるように、「Mozillageckodriverが見つかりません。」だそうです。
解決方法を調べると、2つのやることが見えてきました!

  1. geckodriverをダウンロードする
  2. usr/binにgeckodriverファイルを移動

これを実行できれば、解決できそうやなぁ🤔

解決方法

geckodriverをインストールすれば解決できます。

$ brew install geckodriver
Updating Homebrew...
==> Downloading https://homebrew.bintray.com/bottles/geckodriver-0.27.0.
==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/c1ccd105a99db
#                                                                       ###                                                                     #######                                                                 ###########                                                             ##################                                                      ###########################                                             ###########################################                             ############################################################            ######################################################################## 100.0%
==> Pouring geckodriver-0.27.0.high_sierra.bottle.tar.gz
🍺  /usr/local/Cellar/geckodriver/0.27.0: 6 files, 5.4MB

これで完了です!

【Rspec/エラー】NameError: uninitialized constant Pry::Command::ExitAllの解決方法

こんにちは。

年々寒さに打たれ弱くなっております。

どうもハチマキです。

はじめに

Rspecテストでbinding.pryを使いたいときに発生したこのエラー。
解決方法について書いていこうと思います。

では早速行きましょう!

本日の概要 : NameError: uninitialized constant Pry::Command::ExitAllの解決方法

事象

binding.pryを使いたく、Gemfileにちゃんと追加したのに、featureテストを実行した時にuninitialized constant Pry::Command::ExitAllが発生。。

group :development, :test do
  gem 'pry-rails'
  gem 'pry-byebug'
  gem 'pry-doc'
end

エラー例

エラー内容にも記載してあるように、「ファイルが読み込めない」だそうです。
Gemfileに追加したのになんでや🤔!!?

$ bundle exec rspec spec/features/~~.spec.rb

An error occurred while loading ./spec/features/〜spec.rb.
Failure/Error: require File.expand_path('../config/environment', __dir__)

NameError:
  uninitialized constant Pry::Command::ExitAll
・
・
・

原因

公式ページにも解説されているそうですが、pry-byebugをアップデートする必要があり、アップデートがなされていないことが原因でした。

解決方法

解決するために下記コマンドを実行してアップデートすることで解決できることでしょう!

$ bundle update pry-byebug
Fetching gem metadata from https://rubygems.org/............
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
・
・
・

これで無事に「binding.pry」は動くはず!

【heroku】「Everything up-to-date」が出て、デプロイできないときの解決方法

こんにちは。

最近JavaScriptを触りました。難しい。。

どうもハチマキです。

はじめに

今回は、herokuにアプリケーションをデプロイした際に発生したエラーにハマったため、その解消方法について書いていこうと思います。

では早速行きましょう!

本日の概要 : 「Everything up-to-date」が出て、デプロイできないときの解決方法

事象

作成したアプリケーションをherokuにデプロイした時に「Everything up-to-date」が出て一生デプロイできない。。

エラー例

※herokuはすでにインストール、ログイン済みの状態とします。

$ git push heroku master
Everything up-to-date

デプロイするため、上記コマンドを実行したらEverything up-to-dateが出る。。

原因

結論の原因は、herokuに紐ずけたURLに間違えがありました。

順を追って説明していきたいと思います。

そもそも「Everything up-to-date」エラーの意味は「すべてが最新」の状態にあり、ローカルブランチの内容とリモートブランチの内容に差分が無いという意味です。

エラー原因をググってみると、いくつかのパターンがみられました。

  1. コードの変更がそもそもない
  2. コミットのし忘れ
  3. masterブランチにプッシュしていない

などなど

上記の解決方法はもちろん試しましたが、結局解決できませんでした。。
というのも、今回問題だったのは上記にも記載した$ git remote add herokuで紐ずけたURLに間違えがありました。

解決方法

2つコマンドを叩くことで解決できます。
端的に言うと、登録してあるherokuを一度削除し、正しいURLに紐づけることで解決に至りました。

  • 1つ目:remoteのherokuを一度削除する
$  git remote #このコマンドで一度確認
heroku
origin

$  git remote rm heroku  #herokuを一度削除

$  git remote #herokuが削除されていることを確認
origin
  • 2つ目:リモートリポジトリにherokuを紐づける
$  git remote add heroku https://git.heroku.com/アプリケーション名.git

※$ heroku create 好きなアプリ名で作成した時に発行されたURLに紐づけてください。

$ heroku create 好きなアプリ名
 ›   Warning: heroku update available from 7.42.1 to 7.47.0.
Creating ⬢ アプリ名... done
https://アプリ名.herokuapp.com/ | https://git.heroku.com/アプリ名.git ←ここ!!

最後に!

$ git push heroku master
Counting objects: 10551, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (8647/8647), done.
Writing objects: 100% (10551/10551), 97.55 MiB | 4.25 MiB/s, done.
Total 10551 (delta 1624), reused 8647 (delta 1241)
・
・
・

やっと動き始めました。。。

【Rails】VCRでハマったエラー「VCR::Errors::UnhandledHTTPRequestError:」の解決方法

こんにちは。

この世の匂いの中で一番好き!と言っても過言でない金木犀
ついに金木犀の香りミストを購入してしまいました。
家に振りまいてやろうと思います。

どうもハチマキです。

はじめに

今回VCRを使った際のエラーに結構ハマってしまいました。
エラー解決を見つけるのに時間がかかったため、今回はこのエラーの解決方法に関して記載していきます。

では早速行きましょう!

本日の概要 : VCR::Errors::UnhandledHTTPRequestError:の解決方法

VCRとは?

テストで使う『HTTP通信』を1回目に記録しておいて、2回目以降のテストでの実行時間を短縮し、効率的なテストを支援してくれるGemです。
具体的に言うと、テスト中に過去に投げたリクエストをカセット(cassete)に記録しておいて、その後再度同じリクエストが投げれられた場合はサーバーではなく、記録しておいたカセットからリクエストの結果を取り出すというものです。

事象

Rspecテストで、別のDBレコードを取得する必要がありVCRのGemを使用しました。
今回は、外部APIとのやりとり情報をテキスト情報で保存して、それをテスト内で読み込みたいがエラーが発生。。。

エラー例

1) testが通ること
     Failure/Error:~~
     
     VCR::Errors::UnhandledHTTPRequestError:

       ================================================================================
       An HTTP request has been made that VCR does not know how to handle:
         GET http://~~
     
       VCR is currently using the following cassette:
         - /Users/アプリ名/spec/vcr/features/~~.yml
         - :record => :once
         - :match_requests_on => [:method, :uri]
     
       Under the current configuration VCR can not find a suitable HTTP interaction
       to replay and is prevented from recording new requests. There are a few ways
       you can deal with this:
     
         * If you're surprised VCR is raising this error
           and want insight about how VCR attempted to handle the request,
           you can use the debug_logger configuration option to log more details [1].
         * You can use the :new_episodes record mode to allow VCR to
           record this new request to the existing cassette [2].
         * If you want VCR to ignore this request (and others like it), you can
           set an `ignore_request` callback [3].
         * The current record mode (:once) does not allow new requests to be recorded
           to a previously recorded cassette. You can delete the cassette file and re-run
           your tests to allow the cassette to be recorded with this request [4].
         * The cassette contains 1 HTTP interaction that has not been
           played back. If your request is non-deterministic, you may need to
           change your :match_requests_on cassette option to be more lenient
           or use a custom request matcher to allow it to match [5].
     
       [1] https://www.relishapp.com/vcr/vcr/v/3-0-0/docs/configuration/debug-logging
       [2] https://www.relishapp.com/vcr/vcr/v/3-0-0/docs/record-modes/new-episodes
       [3] https://www.relishapp.com/vcr/vcr/v/3-0-0/docs/configuration/ignore-request
       [4] https://www.relishapp.com/vcr/vcr/v/3-0-0/docs/record-modes/once
       [5] https://www.relishapp.com/vcr/vcr/v/3-0-0/docs/request-matching
       ================================================================================

原因

今回問題だったのは、VCR is currently using the following cassette:でした。
いわゆるカセットファイル(yml)にすでに同様のファイルが記憶されていたため、エラーが発生しました。
(過去に同様のカセットファイル名でコマンドを実行していたため、記憶されていたのでしょう。)

※定義しているカセットファイル(yml)がないか検索してみましょう。

解決方法

すでに記憶(存在)しているカセットファイル(yml)を削除します。

$ rm spec/vcr/features/~~yml 

これで再度テスト実行したらエラーが解消してました。
ファイルの内容を再度変更したい場合は、作成されているカセットファイルを削除し、再度テスト実行すると新しいカセットファイルが作成されます。

Gulp導入時に発生したエラーを解決していく

こんにちは。

今日から異様に寒くなりました。
でも暖房はまだつけない!負けない!

どうもハチマキです。

はじめに

CoffeeScriptコンパイルする作業が必要だったため、コンパイルを自動化するgulpを導入しました。
今回導入にあたり、いくつかエラーが発生し、ハマった点がありましたのでその解決方法を書いていきたいと思います。
導入までに3つほどエラーが発生しましたが、無事完了しました。

では、早速いきましょう〜!!(〜はチルダと言います)

本日の概要 : Gulp導入時に発生したエラーを解決していく

まずはgulp(ガルプ)とは?

Node.jsをベースとしたビルドシステムヘルパーです。
gulpを使うことで、様々な作業を自動化することができます。

※例えば、Webサイト構築に必要な処理をタスクとして自動化してくれるプログラムで、作業の効率化に使われています。

なぜ自動化が必要なのか?

良くSassやSylusなどのCSSプリプロセッサを使うときや、CoffeeScriptやTypeScriptといったAltJSを使うときなど、コンパイルという作業が毎回必要になります。
コンパイルだけならば各種のコンパイラに付いているwatch機能を利用して変更を監視することはできます。が、コンパイル後に「圧縮・結合して、ブラウザの自動更新も行いたい」と思った場合はどうでしょう。
これらの作業を毎回手動で実行するのは手間がかかるため、これらの作業をgulpのタスクにし、自動化することで作業を効率的に進めることができます。

開発環境の準備

開発環境の準備の前にgulpを導入する上で、注意すべき点を先に述べたいと思います。

注意すべき点は、Node.jsとgulpのバージョンの組み合わせです。
最新のNode.jsをインストールする場合、gulpのバージョンが4以上でないと動きません。
※今回は、nodeのバージョンv10.22.1に合わせてgulpの導入するために、gulpのバージョンを下げて進めていきます。

・パターン例
$ node -v
v10.22.1

$ gulp -v
CLI version: 2.3.0
Local version: 3.9.1
ーーーーーーーーーーーーー
$ node -v
v14.13.1

$ gulp -v
CLI version: 2.3.0
Local version: 4.0.2
手順① Node.jsをインストール
$ brew install node@10 ※今回は10系をインストールしていきます

$ node -v
-bash: node: command not found

まずここで、一つ目のエラーが発生しました。
bash: node: command not foundのエラーを解決するためには、.bash_profileにパスを追加することで解消が出来ます。(エラーがでなければ手順②へ)

下記コマンドを実行していきます。

$ echo 'export PATH="/usr/local/opt/node@10/bin:$PATH"' >> /Users/ユーザ名/.bash_profile #>>はファイル末尾に追記されます

$ source /Users/ユーザ名/.bash_profile  #シェルの設定ファイルを反映させる

$ node -v #再度バージョンを確認すると、無事に確認出来ました
v10.22.1
手順② npmによるインストール
$ npm install
[
audited 687 packages in 4.809s

25 packages are looking for funding
  run `npm fund` for details

found 30 vulnerabilities (9 low, 10 moderate, 11 high)
  run `npm audit fix` to fix them, or `npm audit` for details

$ npm -v
6.14.8

npmはインストール出来ましたが、ここでもエラーが発生しました。
手順③で、2つ目のエラーを解決していきます。

手順③ gulpのインストール

上記エラーを解決するためには、gulpをインストールする必要があります。
下記2つのコマンドを実行していきましょう。

$ npm install -g gulp #gulpをグローバルインストール
$ npm install --save-dev gulp #gulpをローカルインストール

$ gulp -v
CLI version: 2.3.0
Local version: 4.0.2

$ gulp
Requiring external module coffee-script/register
[AssertionError [ERR_ASSERTION] [ERR_ASSERTION]: Task function must be specified

無事にgulpのインストールが完了しましたが、gulpコマンドを実行すると3つ目のエラーが新たに発生しました。

これを解決するためには、冒頭にも記載したバージョンの組み合わせを整える必要があります。
ですので、バージョンを指定し直すことで解決にたどり着けます。

$ sudo npm install --save-dev gulp@3.9.1

$ gulp -v
CLI version: 2.3.0
Local version: 3.9.1

$ node -v
v10.22.1

$ gulp
[15:29:22] Requiring external module coffee-script/register
[15:29:22] Using gulpfile ~/アプリ名/gulpfile.coffee
[15:29:22] Starting 'clean'...
[15:29:22] Starting 'coffee-lint'...
[15:29:22] Starting 'compile-coffee'...
[15:29:22] Starting 'copy-pure-js'...
[15:29:22] Starting 'watch'...
[15:29:22] Finished 'watch' after 34 ms
[15:29:22] Finished 'copy-pure-js' after 79 ms

omg/client/ConvertRecord.coffee
  ✖  line 9   Line exceeds maximum allowed length  Length is 100, max is 80
  ✖  line 46  Line exceeds maximum allowed length  Length is 81, max is 80
  ✖  line 51  Line contains a trailing semicolon
  ✖  line 56  Line contains a trailing semicolon

✖ 4 errors
.
.
.

これで無事gulpが正常に動作し、導入が完了です!
お疲れ様でした。