Herokuへpushするときに「Failed to install gems via Bundler.」と「NoMethodError: undefined method `factory_bot’ for #<Rails::Application::Configuration:0x0000556cf580a310>」が出た
まさかこんなにハマるとは思いませんでした...。
備忘録としてハマったエラーの対処法をまとめます。
流れと結論
Herokuへpushする際に2つのエラーに遭遇しました。
1.「Failed to install gems via Bundler.」
→ ローカルのbundlerのバージョンをherokuと一致させる
→ Gemfile.lockにplatform の追加
2.「NoMethodError: undefined method `factory_bot’ for #
→ config/application.rb の config.factory_bot.definition_file_paths = [“spec/factories”] を削除
これによって無事Herokuにpushできました。
1つ目のエラー解決方法
$git push heroku main を実行したところ以下のようなエラーが発生。
Enumerating objects: 839, done. Counting objects: 100% (839/839), done. Delta compression using up to 8 threads Compressing objects: 100% (780/780), done. Writing objects: 100% (839/839), 405.51 KiB | 7.37 MiB/s, done. Total 839 (delta 438), reused 0 (delta 0) remote: Compressing source files... done. remote: Building source: remote: remote: -----> Building on the Heroku-20 stack remote: -----> Determining which buildpack to use for this app remote: ! Warning: Multiple default buildpacks reported the ability to handle this app. The first buildpack in the list below will be used. remote: Detected buildpacks: Ruby,Node.j remote: See https://devcenter.heroku.com/articles/buildpacks#buildpack-detect-order remote: -----> Ruby app detected remote: -----> Installing bundler 2.2.11 remote: -----> Removing BUNDLED WITH version in the Gemfile.lock remote: -----> Compiling Ruby/Rails remote: -----> Using Ruby version: ruby-2.7.2 remote: -----> Installing dependencies using bundler 2.2.11 remote: Running: BUNDLE_WITHOUT='development:test' BUNDLE_PATH=vendor/bundle BUNDLE_BIN=vendor/bundle/bin BUNDLE_DEPLOYMENT=1 bundle install -j4 remote: Fetching gem metadata from https://rubygems.org/............ remote: Your bundle is locked to msgpack (1.4.1), but that version could not be found in remote: any of the sources listed in your Gemfile. If you haven't changed sources, that remote: means the author of msgpack (1.4.1) has removed it. You'll need to update your remote: bundle to a version other than msgpack (1.4.1) that hasn't been removed in order remote: to install. remote: Bundler Output: Fetching gem metadata from https://rubygems.org/............ remote: Your bundle is locked to msgpack (1.4.1), but that version could not be found in remote: any of the sources listed in your Gemfile. If you haven't changed sources, that remote: means the author of msgpack (1.4.1) has removed it. You'll need to update your remote: bundle to a version other than msgpack (1.4.1) that hasn't been removed in order remote: to install. remote: remote: ! remote: ! Failed to install gems via Bundler. remote: ! remote: ! Push rejected, failed to compile Ruby app. remote: remote: ! Push failed remote: Verifying deploy... remote: remote: ! Push rejected to score-log. remote: To https://git.heroku.com/score-log.git ! [remote rejected] HEAD -> main (pre-receive hook declined) error: failed to push some refs to 'https://git.heroku.com/score-log.git'
Herokuでのbundlerが2.2.11となっているがローカルのbundlerは2.1.4となっていました。
ローカルのbundlerのバージョンを2.2.11とするために以下の記事に記載されていることをそのまま実行しました。
これでエラー解決と思いきや、またも同じ「Failed to install gems via Bundler.」のエラー。
いろいろ調べてみると、一部の Mac では Gemfile.lock の PLATFORM が不足しているためにHerokuへのpush時にエラーが出るとのこと。
$ bundle lock --add-platform ruby $ bundle lock --add-platform x86_64-linux $ bundle install
ここに関してはあまり理解できていません......
2つ目のエラー解決方法
これでやっとHerokuへpushできると思ったのですが、またエラーに遭遇しました。
remote: ! Could not detect rake tasks remote: ! ensure you can run `$ bundle exec rake -P` against your app remote: ! and using the production group of your Gemfile. remote: ! rake aborted! remote: ! NoMethodError: undefined method `factory_bot' for #<Rails::Application::Configuration:0x0000559ccfd5f860>
factory_botが未定義と出ています。
Gemfileやfactory_bot周辺を調べましたが、原因が分からずメンターさんに相談しました。
config/application.rbに
config.factory_bot.definition_file_paths = [“spec/factories”]
が追加されていることが原因ではないかとのこと。
以前factory_bot導入時のエラー対処で上記をconfig/application.rbに追加していました。
gem 'factory_bot_rails' をテスト環境にのみ入れているにも関わらず、config/appcliation.rbに config.factory_bot.definition_file_paths = [“spec/factories”] を追加したことで本番環境にもfactory_botを入ってしまっていたようです。
そのためpushする際にfactory_botが未定義となっていました。
上記の記述を削除することで無事Herokuへpushすることができました。
config.factory_bot.definition_file_paths = [“spec/factories”]
私の場合はこの記述は不要でしたが、必要であれば
・config/environments/development.rb
・config/environments/test.rb
の2箇所に追加すればいいようです。
Rails6での flatpickr 導入
Rails6 から Webpacker が導入されたため、flatpickr の導入がこれまでと異なり苦戦したので備忘録として記録します。
下記の記事を参考に導入しました。
dzone.com
flatpickrの導入
1.Yarn に必要なライブラリをターミナルで追加
$ yarn add bootstrap jquery popper.js flatpickr
2.jQuery を使用するためのコードを追記
config/webpack/environment.jsに記述
const { environment } = require('@rails/webpacker') const webpack = require('webpack') environment.plugins.append('Provide', new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' })) module.exports = environment
3.CSSでWebpackerを扱う
app/views/layouts/application.html.erbに以下の記述を追加
<!-- stylesheet_link_tag の行の下に記述する --> <%= stylesheet_pack_tag "application", media: "all", "data-turbolinks-track": "reload" %>
javascriptディレクトリ内にCSS用のファイルを作成
mkdir app/javascript/stylesheets touch app/javascript/stylesheets/application.scss
作成したapp/javascript/stylesheets/application.scssファイルに次を追加
@import "flatpickr/dist/flatpickr.css";
4.JavaScript ファイルを読み
app/javascript/packs/application.js に以下のコードを追記
require("flatpickr") import flatpickr from "flatpickr"; document.addEventListener("turbolinks:load", () => { flatpickr("[class='flatpickr']", { }) }) // stylesheets require("../stylesheets/application.scss") })
あとはclassに 'flatpickr' を指定すば表示できるはずです。
<%= form_with model: @log, local: true do |f| %> <%= hidden_field_tag :score_id, @score.id %> <div> <%= f.text_area :content, placeholder: "練習記録", class: "text-box" %> </div> <div> <%= f.text_field :start_time, placeholder: "日付を選択", class: 'flatpickr' %> <%= f.submit "記録する", class: "record-btn" %> </div> <% end %>
おまけ
flatpickrは様々なカスタマイズが可能です。
今回は以下のようにカスタマイズを行いました。
・スマートフォンでも使用
・日付の選択を今日まで可能に
document.addEventListener("turbolinks:load", () => { const TODAY = new Date(new Date().setHours(0, 0, 0, 0)) flatpickr("[class='flatpickr']", { // スマートフォンでもカレンダーに「flatpickr」を使用 disableMobile: true, // 今日までを選択可能 maxDate: TODAY }) })
PostgreSQLでテーブルの型をintegerにしたらPG::DatatypeMismatch: ERRORで失敗した
テーブルでstring型 を integer型 に変更しようとしたらマイグレーションができませんでした。
== 20210213101041 ChangeDatatypeStatusOfScores: migrating ===================== -- change_column(:scores, :status, :integer) rails aborted! StandardError: An error has occurred, this and all later migrations canceled: PG::DatatypeMismatch: ERROR: column "status" cannot be cast automatically to type integer HINT: You might need to specify "USING status::integer".
エラー文には
「statusカラムは自動的に整数型にできないよ」
「ヒント:USING句を使用しましょう」
というようなことが書かれています。
ヒントのまんま"USING status::integer"を使ってみましたが、マイグレーションできませんでした...
調べてみたところ下記のように記述するようです。
変更したいデータ型 CAST(カラム名 AS 変更したいデータ型)
CAST 関数は引数に指定した値(カラム名)を別のデータ型に変換するために使用します。
class ChangeDatatypeStatusOfScores < ActiveRecord::Migration[6.0] def change # change_column :scores, :status, :integer (変更前) change_column :scores, :status, "integer USING CAST(status AS integer)" end end
これでデータ型の変更ができました。
【Rails】ログイン機能(devise)の導入方法
1.Gemfileに 「gem 'devise'」を追記
gem 'devise'
記述箇所によって開発環境のみやテスト環境のみで使えるように指定もできる。
どの環境でも使えるようにするには group :development, :test do よりも上に記述する。
ターミナルで以下のコマンドを実行してgemをインストール。
$ bundle install
2.設定ファイルを作成
deviseはGemのインストールをするだけでは使用できない。そのため devise 専用のコマンドを利用して設定ファイルを作成。
ターミナルで以下のコマンドを実行。
$ rails g devise:install
3.モデルの作成
devise を使用する際のモデルの作成。
通常の方法 rails g model ではなく、devise 専用のコマンドを使用することでログイン機能に対応したモデルを作成することができる。
ターミナルで以下のコマンドを実行。
$ rails g devise User
4.マイグレーションを実行
マイグレーションを実行しテーブルを作成。
$ db:migrate
5.viewファイルを作成
今のままだと views ディレクトリの中にファイルが存在しないのでカスタマイズができない。
devise 専用のコマンドを利用してビューファイルを生成する。
$ rails g devise:i18n:views
【Rails】カラムの追加・編集・削除
共同開発でカラムの削除が必要になったので、追加・変更・削除の方法についてまとめました。
すでに実行済みのマイグレーションファイルは修正や上書きをすることはできないので、変更を加える為に別のマイグレーションファイルを作成し実行する必要があります。
カラムの追加
ターミナルで以下のコマンドを実行しマイグレーションファイルを作成。
$ rails g migration add_カラム名_to_テーブル名 カラム名:型
マイグレーションファイル
class AddTitleToTexts < ActiveRecord::Migration[6.0] def change add_column :texts, :title, :string end end
カラムの編集
ターミナルで以下のコマンドを実行しマイグレーションファイルを作成。
$rails g migration rename_変更前のカラム名_column_to_テーブル名
マイグレーションファイルのchangeメソッドの中に以下を記述する。
rename_column :テーブル名, :変更前の名前, :変更後の名前
マイグレーションファイル
class RenameTitleColumnToTexts < ActiveRecord::Migration[6.0] def change rename_column :texts, :title, :song_title end end