- 投稿日:2020-07-27T23:58:59+09:00
マイグレーションファイルやテーブルの削除手順書
Railsを使い始めた頃に、マイグレーションファイルの扱いに苦戦していた時がありました。
手順や状態の確認もしないまま「いらないマイグレーションだから消してしまえ!」とか...部分的なコマンドだけではなく、「実際の流れ」や「意図」を交えて書いていきます。
スクショも使ってあるので、見難かったらすみません...汗
$
は入力しなくても大丈夫です!はじめにマイグレーションファイルの状態を確認します
プロジェクト内のターミナルで下記を実行
$ rails db:migrate:statusすると、現在実行されているマイグレーションファイルの状態が分かります。
※ 行いたい事:
一番下にあるCreate text matelials
のマイグレーションファイルで作成したテーブルを削除してからマイグレーションファイルも削除したい時の説明です。1: Statusの状態を確認する
左側のStatusは全て
up
になっています。upになっているということはデータベースは、このマイグレーションファイルの構造を取り入れている(マイグレーションファイルはすでに実行済みのファイル)ということです。
up状態のマイグレーションファイルは削除したり編集したりしてはいけません。状態がわかったので次は、
2: upをdownを切り替える方法
ここで必要な情報は Migration ID の数字!!
今回で言うと20200608181608
です。プロジェクト内のターミナルで下記を実行
$ rails db:migrate:down VERSION= "Migration ID"今回だと下記になります。
$ rails db:migrate:down VERSION=20200608181608もう一度Statusを確認します
rails db:migrate:status
を実行
ちゃんとdown
になっています。
down状態なので編集と削除ができます。3: テーブルを編集、削除する手順
"db/maigrate"内にあるマイグレーションファイルを開いて追記します。
(↑ は後に重要なことなので、太めに書いておきました)
今回は、"db/maigrate"内にある
20200608181608_create_text_matelials.rb
ファイルを開きます。中のコードが下記の時
class CreateTextMatelials < ActiveRecord::Migration[6.0] def change end endこの中へ
drop_table :削除したいテーブル名
を追記します。
※自身のテーブル名を確認したい場合はdb/schema.rb
の中を確認してください。
※注意:ActiveRecord::Migration [6.0] の部分は自身のRailsのバージョンに指定してください。(例) [5.1]等「Railsのバージョンがわからない...」場合は
ターミナルでrails -v
を実行するとわかりますよ。追記後は下記です。
class CreateTextMatelials < ActiveRecord::Migration[6.0] def change drop_table :text_matelials end end削除する追記が完了したら
rails db:migrate
を実行します。
これでテーブルの削除ができました。
db/schema.rb
の中を確認すると指定したテーブルは削除されているはずです。【何が起きていたのか文章で言うと..】
drop_table :text_matelials
としてtext_matelialsテーブルを削除する内容を記述したファイルを実行したのでテーブルを削除できたというわけです。
rails db:migrate:status
でステータスを確認してみると
rails db:migrate
を実行したのでStatusの状態はupになっています。
こんな感じでしょうか..引き続き"マイグレーションファイルの削除"を説明します。
4: マイグレーションファイルを削除する手順
今は、
"db/maigrate"内にある
20200608181608_create_text_matelials.rb
ファイルをこのまま削除する方法です。プロジェクト内のターミナルで下記を実行
$ rm -rf db/migrate/20200608181608_create_text_matelials.rb
rails db:migrate:status
を実行して、ステータスを確認してください。
削除されていることがわかると思います。5: マイグレーションを間違って削除してしまった場合
データベースに反映したマイグレーションファイルを不要だと思い、誤って削除した時に
rails db:migrate:status
を実行してステータスを確認すると下のように"NO FILE"と出てきてしまった時の対処です。手順に入る前になぜNO FILE になっているのか状況を説明します。
【 NO FILE になっている状況の説明 】
上の画面から分かることはStatusが NO FILE となっているマイグレーションがupになっている!
ということはデータベースはこのマイグレーションファイルの構造を取り入れているということですね。up状態のマイグレーションファイルを手動でカラムの削除したり、カラムを使っていないということでマイグレーションファイルを削除したのかもしれません。
NO FILE になるのは、
マイグレーションファイルを削除してもdb/migration内のschema_migrationsテーブルにバージョンが保存されているためです。schema_migrationsテーブルから削除してしまったマイグレーションファイルのバージョンが保存されているレコードを削除すればこの表示は消えます。
※ 単にdb/migration/schema.rbの内部を削除しただけでは
rails db:migrate
するとまた復活してしまいます。6: NO FILE状態のschema.rb内のテーブルとNO FILEを削除する手順
[3: テーブルを編集、削除する手順]で説明したように
"db/maigrate"内にあるマイグレーションファイルを開いて追記が必要
ですが、今回の場合はマイグレーションファイルが無いので、マイグレーションファイルを作成するところからはじめます。
はじめに
rails db:migrate:status
を実行してMigration ID を確認しましょう。今回だと
20200601140204
になります。マイグレーションファイルを作成する
rails プロジェクトの db/migrateに移動
プロジェクト内のターミナルで下記を実行$ cd db/migrateマイグレーションファイルを作成します。
db/schema.rb
の中でテーブルを確認した時に、
今回はconversations
テーブルを削除したい。とすると
touch マイグレーションID_ファイル名.rb
(※最終的に削除します。一時的な使用なのでのでファイル名はなんでも構いません)
(※もしテーブルを使いたい場合は、適した名前にしてください)今回は下記のようにしました
プロジェクト内のターミナルで実行$ touch 20200601140204_tmp.rbこれで
tmp.rb
というマイグレーションファイルができました。
次に
[3: テーブルを編集、削除する手順]
[4: マイグレーションファイルを削除する手順]
を行います。...と省略されると不安に思う人(自分..)もいると思うので、ダブりますが続きも書いておきますね。
テーブルを編集、削除する
エディタから
db/migrate
内の
20200601140204_tmp.rb
ファイルを開いて下記を記述
※注意:ActiveRecord::Migration [6.0] の部分は自身のRailsのバージョンに指定します。(例) [5.1]等
「Railsのバージョンがわからない...」場合は
ターミナルでrails -v
を実行するとわかります。class Tmp < ActiveRecord::Migration[6.0] def change end endschema.rb内にテーブルを作成していないファイルならこのまま削除しますが今回は先ほど作成したマイグレーションファイルを使ってschema.rb内のテーブルを削除したいので更に
drop_table :削除したいテーブル名
を追記します。※テーブル名を確認したい場合は
db/schema.rb
の中を確認。今回は
conversations
テーブルを削除したいとします。class CreateConversations < ActiveRecord::Migration[6.0] def change drop_table :conversations end end編集が終了したので
rails db:migrate
をしてテーブルを削除します。
db/schema.rb
の中を確認すると指定したテーブルが削除されていると思います。マイグレーションファイルを削除する
残るは先ほどNOFILE状態だったファイル(現在の 20200601140204_tmp.rb)ですね。
まずはup状態をdown状態にします!!...と
その前にdrop_table :conversations
があるとdownできないので削除しておきましょう。down状態にするのに必要な情報は Migration ID の数字です。
今回で言うと20200601140204
ですね。プロジェクト内のターミナルで下記を実行
$ rails db:migrate:down VERSION=20200601140204
rails db:migrate:status
を実行してステータスを確認。
downになっていればOKです!"db/maigrate"内にある
20200601140204_tmp.rb
ファイルをこのまま削除します。プロジェクト内のターミナルで下記を実行
$ rm -rf db/migrate/20200601140204_tmp.rbステータスを確認
rails db:migrate:status
を実行
するとはじめにNOFILEだったものも削除されていることがわかるります!自分も経験した勘違い
サーバーにアップされた時に、マイグレーションファイルは全てdown状態なので
rails db:migrate
コマンドを実行します。例えばusersテーブルを作成するマイグレーションファイルを削除してしまって、その後にusersテーブルにカラムを追加するマイグレーションファイルがあった時、存在しないusersテーブルにカラムを追加することはできないのでエラーが出てしまいます。
ローカルではエラーは出ないのに、サーバーにアップしたらなぜかエラーになる...
こんな状況になるときがありました。ローカル環境ではusersテーブルが削除される前に
rails db:migrate
で実行してありマイグレーションファイルによって既に作成されているので、マイグレーションファイルを誤って削除してしまった場合でもエラーが出ない。
ただ、
サーバーにアップされた時は、マイグレーションファイルは全てdown状態になっているのでrails db:migrate
コマンドを実行することになります。でも、usersテーブルを作成するマイグレーションファイルを削除してしまっている状態では存在しないusersテーブルにカラムを追加することはできないぞ!とエラーが出てしまう。
「ローカルとサーバーにアップした時で上記のような齟齬がないようにするため」と、
「チーム開発している場合に、他の開発者を混乱させる要員になる」ので注意して行う。
マイグレーションファイルを削除する際は必ずdown状態になっているのを確認してから編集や削除する!ということを忘れないようにしたいですね。手動で削除してしまえばいいだろ!とはいかないのです。
最後に
意味がわからない..と焦りますよね。
私もそうです。(現在進行形)笑
今回は長くなってしまいましたが、「コマンドだけ」とか「ここを参考」とかをあえて使わず、内容ダブってもいいから書こう!その方が流れが分かりやすいと思い書きました。初学者目線だと「流れ」が分かれば、理解は早いと感じてます。
少しでも参考になれば嬉しいです!間違い等ございましたら、勉強して修正させて頂きますのでご指摘ください!
以上です。おつかれさまでした!
- 投稿日:2020-07-27T23:13:19+09:00
RubyとRailsの勉強録0
Railでいろんなアプリ作りたいんや!
っと意気込んで、プログラミングを始めてみました。
これまで、プログラミングはMQLという超マイナーな言語を軽くしか触ってないので、本格的に勉強するのは始めてです。
会社では、プログラミングとは無関係な仕事をしています。
そのため、モチベーションが下がらいないようにするため、また、分からないことやこれまで何を考えて勉強してきたかを記録する意味でもブログを開始しようと思います。ちなみ、ブログを書くのも初心者ですし、Qiitaの使い方もよく理解していないので、ブログを書きながら勉強していこうと思います。
なぜRubyを勉強しようと思ったか
クラウドソーシングのサイトを作ってみたかったからです。
他にも、ツイッターとかインスタグラムもどきを簡単に作れるってすごくない!?という安直な理由からです。
他の言語でも作れるんでしょうけど、なんとなく自分の作りたいものを一番表現しやすい言語なのかなと思いました。今までやってきたこと
- 本(なお買っただけの模様)
- プロを目指すためのRuby入門
- 現場で使えるRuby on Rails5速習実践ガイド
- ドットインストール(やった順)
- Ruby入門 (全26回)
- Ruby on Rails 5入門 (全28回)
- はじめてのRuby (全9回)
- UNIXコマンド入門 (全24回)
- Active Record入門 (全19回)
以上のことをやってきたのですが、、、
全くわからん!!
なんとなくブログっぽいものができたけど、なぜできたのか一切理解できていない!!
と、危機感を覚えたのもブログを開始した理由の一つです。
これからやること
HTML、CSS、JavaScriptは必須!と色々書かれていますが、モチベが上がらないので、必要になったらやろうと思います。
だって早くアプリ作りたいじゃん?
ということで、とりあえずrailsを中心にやりながら、必要になったものを必要になった時だけ勉強しようと思います。
これで良いのか分かりませんが、これが一番モチベ上がります!w
ということで、次回から早速railsの勉強を記録していこうと思います。
- 投稿日:2020-07-27T22:50:25+09:00
アウトプット
- 投稿日:2020-07-27T22:36:30+09:00
Ruby Error[Your Ruby version is 2.6.3, but your Gemfile specified 2.6.5] とでた時
ユーザー認証機能を実装中サーバーを再起動した時にそれは起きました。
Ruby Error[Your Ruby version is 2.6.3, but your Gemfile specified 2.6.5]本来であればruby 2.6.5のはずなのに。。なにもいじっていないのに。。環境設定の画面を確認します。
%less ~/.zshrcLinuxコマンドlessでファイルの中身を確認することができます。
export PATH="/usr/local/opt/mysql@5.6/bin:$PATH" export BASIC_AUTH_USER='admin' export BASIC_AUTH_PASSWORD='2222'どうやら環境変数を定義した際にrvenvの設定を変えてたみたいです。
eval "$(rbenv init -)" export PATH="/usr/local/opt/mysql@5.6/bin:$PATH" export BASIC_AUTH_USER='****' export BASIC_AUTH_PASSWORD='****'設定を変えて更新したいと思います。
% source ~/.zshrc% ruby -v ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-darwin19]無事元に戻りました。Macでは元々rubyの環境が元々インストールされているみたいで環境を変えたことによりそっちの方が適応されてたみたいですね。
- 投稿日:2020-07-27T21:40:42+09:00
Railsで認証APIを作る
作るもの
ターミナル$ curl -X POST -H 'Content-Type:application/json' -d '{ "mail": "test", "password": "test" }' http://localhost:3000/api/v1/auth # => unauthorized or auth_tokenモデルの作成
ターミナル$ rails g model user mail:string password:string auth_token:token
でモデルを作成し、
db/migrate/YYYYMMDDHHMMSS_create_users.rb- t.string :auth_token + t.string :auth_token, charset: 'utf8', collation: 'utf8_bin'と編集してtokenの衝突を防いだ後、(参考)
ターミナル$ rails db:migrate
テストデータの登録
db/seeds.rbUser.create([{ mail: "test", password: "test" }])と編集して、
ターミナル$ rails db:seed
※
rails db:seed
コマンドはdb/seeds.rb
を実行しているだけなので、実行した分だけデータが追加される。(データの重複が起きる場合がある。)コントローラーとルーティング
app/controllers/api/v1/users_controller.rbmodule Api module V1 class UsersController < ApplicationController def auth user = User.find_by(mail: params[:mail], password: params[:password]) if user == nil render plain: "unauthorized", status: :unauthorized else user.regenerate_auth_token render plain: user.auth_token end end end end end
auth_token
をtoken
属性で作っているのでuser
モデルにregenerate_auth_token
というトークン再生成メソッドが追加されている。config/routes.rbRails.application.routes.draw do namespace "api" do namespace "v1" do post "auth" => "users#auth" end end end確認
ターミナル# 認証失敗 $ curl -X POST -H 'Content-Type:application/json' -d '{ "mail": "foo", "password": "bar" }' http://localhost:3000/api/v1/auth # => unauthorized # 認証成功 $ curl -X POST -H 'Content-Type:application/json' -d '{ "mail": "test", "password": "test" }' http://localhost:3000/api/v1/auth # => wcHUobhucFFA4zDejr2C3btY使い方
app/controllers/api/v1/foos_controller.rbmodule Api module V1 class FoosController < ApplicationController include ActionController::HttpAuthentication::Token::ControllerMethods before_action :authorized?, only: [:bar, :baz] def bar # 認証が必要な処理 end def baz # 認証が必要な処理 end def qux # 認証が不要な処理 end private def authorized? authenticate_or_request_with_http_token do |token, options| user = User.find_by(auth_token: token) user.present? end end end end end
- 投稿日:2020-07-27T21:21:48+09:00
Mysql2::Error::ConnectionErrorが出た場合
localhost:3000で出たエラーを解決させました
自作アプリの開発中に起きたエラーを紹介します。
環境
・macOS
・Rails 5.2.4.3
・Ruby 2.5.1今日(投稿日)はエンゼルスの大谷投手が693日ぶりに登板と言う事で、めちゃくちゃテレビを見たい気持ちを抑えて、いつも通りの朝活を行う事に。。。
へ?
何だこれは??
一瞬頭が真っ白になってしまいました。
なかなか自作アプリ開発が思う様に進まない中で、もはや自分でアプリを見ることすら出来ないのかと愕然。
5分くらい絶望した後に、取り敢えずエラーの解析から始めました。
Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)って何??
エラーの内容を調べていると結構同じ様なエラーに遭遇されている方が多かったので、その記事を見ていくと、
クライアント(自分のPC) → /var/lib/mysql/mysql.sock にデータを見に行こうとしたら、そんな場所ないじゃん。って感じのエラーなんだと理解。
socketとは
プログラムとネットワークを結ぶ接続口。仲介役。仲介業者。仲人。合コンで言う幹事。
って事で正しい出入り口(ソケット)を探す旅に
socketってどこにあんの??
他の記事を読み漁り、socketの存在を調べました
特に参考にさせてもらった記事
Can't connect to local MySQL server through socket '/tmp/mysql.sock'記事を読み比べる中で
'/tmp/mysql.sock' '/var/lib/mysql/mysql.sock'と言う2つのソケットを見比べて、
「自分のエラーの場合は'/var/lib/mysql/mysql.sock'に行こうとしたが、そんな場所はないと言われているので、そこを見つけて修正すれば良いのか!!」と推測。
で、どこに書いてあんの?
解決法
この記事を読んで私も解決しました
【Rails】ローカル環境におけるmysql接続エラー対処法【Can't connect to local MySQL server through socket】database.yml#修正前 development: <<: *default database: データベース名_development username: root password: <%= ENV['DATABASE_PASSWORD'] %> socket: /var/lib/mysql/mysql.sock #修正後 development: <<: *default database: データベース名_development username: root password: <%= ENV['DATABASE_PASSWORD'] %> socket: /tmp/mysql.sock /var/lib/mysql/mysql.sock → /tmp/mysql.sock に変更してますコードの修正を行ったので、再起動させます。
rails sこれでソケット名が正しくなったので、無事に閲覧が出来ました!!
原因
database.ymlですが、特に自分で何かを記述した訳ではなくて、何かしらの教材や記事を
コピペしてしまう事で、起きやすい事象なのかと思いました。
その分、最初はすごく焦りましたが、今まで気にしなかった所を考えたり、エラー文を調べていく中で、同じ様なエラーに遭遇されている方が多かった事も、自分の中では収穫でした。ymlを一度見てもらうのも良いかも知れません。最後にsocketの
'/tmp/mysql.sock' '/var/lib/mysql/mysql.sock'の箇所ですが、使われている方によっては、
/tmp/mysql.sock → /var/lib/mysql/mysql.sockが正解のパターンも多くあると思いますので、まずは自身のsocketの所在を確認してみてください!!
- 投稿日:2020-07-27T19:30:50+09:00
Rails マイグレーション
マイグレーション
マイグレーションファイルを作成しただけではデータベースは変更されず、マイグレーションを適用して初めてデータベースが変更される。どのマイグレーションファイルが適用されているかは、schema_migrationsというテーブルで管理されている。
また、マイグレーションはデータベースごとに適用する必要があるため、「開発用」「本番用」「テスト」ごとにマイグレーションする必要がある。(※デフォルトでは開発用データベースに対して適用される)
マイグレシーション適用でエラーが出ても、エラーのおきたマイグレーションファイルを適用する前の状態のまま。そのため、そのままコードを修正してマイグレーションを行えば良い
マイグレーション時に使うコマンド集
#「開発用」最新までマイグレーションを適用 rails db:migrate #「本番用」最新までマイグレーションを適用 rails db:migrate RAILS_ENV=production #「テスト」最新までマイグレーションを適用 rails db:migrate RAILS_ENV=test #特定のバージョンまでマイグレーションを適用 ※数字の部分はマイグレーションファイルの数字部分 rails db:migrate VERSION=20200701051010 #バージョンを一つ戻す rails db:rollback #バージョンを指定したステップ数だけ戻す rails db:rollback STEP=3 #バージョンを一つ戻し、1つあげる ※バージョンは最終的には変化しないがバージョンを戻す処理が適切にできているか確認的る rails db:migrate:redo
- 投稿日:2020-07-27T18:54:22+09:00
No route matches [GET] になる原因がフロント要素のjsにある謎
備忘録メモ。都度更新
POSTメソッドをとって欲しいのに、No route matches [GET] になる原因がフロント要素のjsにあるってのが謎だったのでまとめる。
バックエンドからフロントまで結合しているから
railsはバックエンドからフロントエンドまで(一部インフラも)すべてが設計的に結合しているというのが特徴があるみたい。こういうフレームワークをフルスタックフレームワークと呼ばれている。
で、フルスタックフレームワークであるrails全部一個のフレームワークで担っているから、railsの一部であるjs(rails-ujs)は同じくrailsのサーバサイドのコードが吐くHTMLと設計的に結合しています(具体的にはHTMLのdata-method属性をrails-ujsが読み込んでいる)。
簡単に言うと???
railsの内部でフロントエンドとバックエンドが勝手に結合してしまっているので何も知らなくてもいろいろなことをよしなにやってくれる一方で、仕組みを知らないとトラブルシューティングが難しく、railsの推奨する方法の外に行くと大幅に困難になるという問題がある。
う〜ん。とりあえず記録として残して内容を更新していくようにする
- 投稿日:2020-07-27T17:42:50+09:00
[Github初心者]ターミナルで新しいブランチを作成する方法
掲示板を作成中、掲示板の基本機能のみ作ってherokuでデプロイした。
ユーザーログインという新規機能安全にデプロイする為に、新機能開発の前にあらかじめgitでmasterではないブランチを作って、テストを行ってからmasterブランチにmergeを行いたい。ブランチ作成&そのブランチに切り替え
$ git checkout -b create-users-table-model
Switched to a new branch 'create-users-table-model'存在するブランチの確認コマンド
$ git branch
* create-users-table-model masterブランチを切り替える
$ git checkout master
Switched to branch 'master'git checkout create-users-table-model
Switched to branch 'create-users-table-model'新しいDBテーブルの作成
$ rails g migration create_users
〜省略〜 warning: The called method `initialize' is defined here invoke active_record create db/migrate/20200727081835_create_users.rb完成。
ここから開発を行っていく。
- 投稿日:2020-07-27T17:42:50+09:00
[Github初心者]ターミナルで新しいブランチを作成してマスターブランチとマージする方法
掲示板を作成中、掲示板の基本機能のみ作ってherokuでデプロイした。
ユーザーログインという新規機能安全にデプロイする為に、新機能開発の前にあらかじめgitでmasterではないブランチを作って、テストを行ってからmasterブランチにmergeを行いたい。ブランチ作成&そのブランチに切り替え
$ git checkout -b create-users-table-model
Switched to a new branch 'create-users-table-model'存在するブランチの確認コマンド
$ git branch
* create-users-table-model masterブランチを切り替える
$ git checkout master
Switched to branch 'master'git checkout create-users-table-model
Switched to branch 'create-users-table-model'新しいDBテーブルの作成
$ rails g migration create_users
〜省略〜 warning: The called method `initialize' is defined here invoke active_record create db/migrate/20200727081835_create_users.rb完成。
ここから開発を行っていく。
DBに必要カラムを追記して作成
db/migrate/'date'_create_users.rbclass CreateUsers < ActiveRecord::Migration[5.1] def change create_table :users do |t| t.string :username t.string :email t.timestamps #created_atなどが自動で追加される #passwordカラムはあとから追加する end end enduserモデル作成
modelsフォルダの下にuser.rbを追加
models/user.rbclass User < ApplicationRecord end保存。$rails cでuserが作成できるか確認。
- 投稿日:2020-07-27T17:04:30+09:00
ミドルウェア(unicorn + nginx)周辺のメモ
記事を書く目的
Railsでつくったアプリをデプロイしたときの構成として、ミドルウェアにNginxとUnicornを使用しました。
なぜこれらを本番環境で使用するのか調べていて、まとめたいなと思ったのでメモ。ミドルウェア
osとアプリケーションの間に入って働くプログラムのこと。
- Webサーバー(Nginx)
- アプリケーションサーバー(Unicorn)
のこと。
こちらの記事のとおりに構成を実施。
(デプロイ編②)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで - QiitaWebサーバー, アプリケーションサーバーの役割
Webサーバー(Nginx)
静的コンテンツを返す役割を持つもの。
誰がみても同じ内容のもの。
誰かの記事を見るなど、誰がみてもその人の記事の内容は同じなのでそれを表示させるのには、Webサーバーだけで十分。アプリケーションサーバー(Unicorn)
動的コンテンツを返す役割を持つもの。
各ユーザーにより、処理が異なるもの。
ログインだったり、記事を投稿する場合だったりデータベースとのやり取りが必要なもの。RailsにはPumaがある
Rails5からはWebサーバーの役割をもつPumaが標準装備されているとのこと。
ということはPuma + Nginx でもいいのではないか?と思っていたらPumaとUnicornを比較した記事がありました。
↓↓
Pumaの本当の力を引き出す - Qiita結果的にデフォルトのPumaは貧弱なため、Unicornを使った方が処理がスムーズなるけど、ポートフォリオくらいならPumaでも問題はないのかなと。
つまり
デフォルトのPumaは貧弱なので、Unicornを使う。
Unicornを使う場合、ドキュメントではNginxと組み合わせることを推奨しているため、Unicornを選んだ場合、webサーバも自然とNginxになる。
- 投稿日:2020-07-27T15:45:07+09:00
【AWS】【CircleCI】【Terraform】【Rails】CircleCIでECSに自動デプロイをする時にハマったとこ
状況
config.ymlversion: 2.1 orbs: aws-ecr: circleci/aws-ecr@6.11.0 aws-ecs: circleci/aws-ecs@1.2.0Orbsを使用してデプロイを実行しようとすると以下のエラーが発生
An error occurred (ClientException) when calling the DescribeTaskDefinition operation: Unable to describe task definition.
エラー内容と対処
調べると、
aws ecs describe-task-definition
コマンドを叩いて、うまくいかなかった時のエラーであるとわかるcircleciのlogから、awsコマンドを叩いてる部分を探すと以下の記述に出会う
circleciPREVIOUS_TASK_DEFINITION=$(aws ecs describe-task-definition --task-definition ${MY_APP_PREFIX}-service --include TAGS)注意するのは、引っ張りたいタスク定義の
familyの末尾は-service
である必要があるということなので、Terraformでは
task_definition.tfresource "aws_ecs_task_definition" "manabi-app" { family = "app名" #これをapp名-serviceに変更 container_definitions = file("./container_definitions/service.json") task_role_arn = data.terraform_remote_state.iam.outputs.ecs_task_role_arn execution_role_arn = data.terraform_remote_state.iam.outputs.ecs_task_role_arn network_mode = "bridge" }うまくデプロイできた!
- 投稿日:2020-07-27T14:02:26+09:00
Railsのmysql接続でユーザー権限がなくconnection errorになるときの対処法
- 投稿日:2020-07-27T11:54:22+09:00
Rails環境下でjqueryにて画面のバリデーションを設定する
背景
現在、自分が作成しているポートフォリオについて、データの更新、新規登録時にバリデーションをかけたい項目がある。個人的には、Vue.jsを学習中のため、こちらで実施したかったが、いろいろ試した結果について次のとおりにまとめる。
環境
項目 内容 OS.Catalina v10.15.4 Ruby v2.5.1 Ruby On Rails v5.2.4.3 MySQL v5.6 対応手順
【手順1】
1)公式サイトからバリデーションを実行してくれるJSファイルをダウンロードする
jquery-validation-1.19.1/dist/jquery.validate.js
jquery-validation-1.19.1/src/localization/messages_ja.js2)以下に格納する
app/assets/javascripts/jquery.validate.js
app/assets/javascripts/messages_ja.js3)JSファイルの設定
①対象となるフォームオブジェクトのIDを設定する(2行目)
②rulesオブジェクトに対象となるテキストボックスのオブジェクトIDを設定する(4行目)
→ここで、正確なオブジェクトidはデベロッパーツールを使用すること
③対象オブジェクトにバリデーションに引っかかった場合の出力メッセージを設定する(9行目)app/assets/javascripts/genre_edit_vaidate.js1 $(function(){ 2 $("#new_genre").validate({ 3 rules : { 4 "genre[in_genre]": { 5 required: true 6 } 7 }, 8 messages: { 9 "genre[in_genre]": { 10 required: "必須入力です", 11 } 12 } 13 }); 14 });4)htmlファイルの設定
今回例では、ジャンル名の登録テキストボックスに必須バリデーションを設定した。new.html.erb<title>メモのカテゴリを登録</title> <p>ジャンルの追加<br></p> <%= form_for (@genre), url: genres_path(:id), method: :post do |f| %> <%= f.label :id,"ユーザ名" ,class: "com-box" %> <%= f.text_field :user_id ,class: "com-box" ,value: current_user.name, readonly:true %> <%= f.hidden_field :user_id ,value: current_user.id%> <%= f.label :id,"ジャンル名を登録してください" ,class: "com-box" %> <%= f.text_field :in_genre ,class: "com-box" %> <%= f.submit "登録する" %> <% end %>
→「必須入力です」と出力されています。あとはスタイルシートで加工すればOKです。簡単にできました!以上です。
参考文献
【jQuery】RailsでValidation Pluginを使った動的なバリデーションチェックの実装 〜導入編〜
- 投稿日:2020-07-27T11:15:17+09:00
datetimeカラムのデフォルト値について
datetimeカラムのデフォルトを現在時間にしたい
この前提のもと、migrationに
t.datetime :created_at, default: DateTime.nowと安直に書いてmigrationすると、migrationされた日がデフォルト値になってしまう。
datetimeみたいに動的な値は、migrationされた時にしか計算されないためだ、と。
Railsガイド>Active Record マイグレーション>3.5 カラム修飾子設定方法
t.datetime :created_at, default: -> { 'NOW()' }これでdatetimeのデフォルト値を設定できました!
参考
他の記述方法もありました!参考にさせていただきました。
Ruby on Railsのmigrationでdatetimeのデフォルト値をCURRENT_TIMESTAMPにする
- 投稿日:2020-07-27T10:21:18+09:00
devise_token_auth ログアウトのテストコード実装時に苦戦したことをまとめる
devise_token_auth でログアウトのテストコード作成時、エラー解決の情報が少なかったのでまとめます。
※ user の新規登録、ログイン、ログアウト機能を実装しているものとします。
※ FactoryBot を導入してます。headers にログインに必要な情報が入っていないため、エラー発生
エラー発生時のコード
describe "DELETE /v1/auth/user/sign_out" do subject { delete(destroy_v1_user_session_path) } context "トレーナーログアウト時" do let(:user) { create(:user) } it "トークンを無くし、ログアウトできる" do subject expect(response).to have_http_status(200) end end endエラー内容
Failure/Error: expect(response).to have_http_status(200) expected the response to have status code 200 but it was 404正常なレスポンス(200)ではなく、リクエストが存在しない(404)エラーが出てます。との内容。
subject の下に binding.pry を入れ、デバック画面にしuser
を実行#<Trainer id: 532, provider: "email", uid: "6_hannah@emmerich.name", allow_password_change: false, name: "松本 七海", nickname: nil, email: "6_hannah@emmerich.name", address: nil, birthday: nil, created_at: "2020-07-26 06:10:35", updated_at: "2020-07-26 06:10:35">user の中にデータがあることを確認できました。
次に headers 情報を確認するため、response.headers
を実行。{"X-Frame-Options"=>"SAMEORIGIN", "X-XSS-Protection"=>"1; mode=block", "X-Content-Type-Options"=>"nosniff", "X-Download-Options"=>"noopen", "X-Permitted-Cross-Domain-Policies"=>"none", "Referrer-Policy"=>"strict-origin-when-cross-origin", "Content-Type"=>"application/json; charset=utf-8", "Cache-Control"=>"no-cache", "X-Request-Id"=>"a2ad39e6-d2b2-4ae8-93c1-5ddcd2ea22d1", "X-Runtime"=>"0.010570", "Content-Length"=>"71"}headers の情報は返ってきましたが、ログアウトに必要な情報
access-token
、client
、uid
が入ってないことが分かります。
headers にログアウトに必要な情報が入ってないから、404の異常系のエラーが発生している。
新規作成時、ログイン時にトークン情報が発行され、その情報をもとにログアウトの処理を行うのですが、現状のコードでは user の情報は作成されても、トークン情報は作成されていない状況です。
なので、トークン情報を入れてあげましょう。describe "DELETE /v1/auth/user/sign_out" do subject { delete(destroy_v1_user_session_path, headers: headers) } context "トレーナーログアウト時" do let(:user) { create(:user) } let(:headers) { user.create_new_auth_token } it "トークンを無くし、ログアウトできる" do subject expect(response).to have_http_status(200) end end end
create_new_auth_token
メソッドで、必要なメタデータ全てを含む新しい認証トークンを作成します。
subject の下に binding.pry を入れheaders
を実行し、データが入っていればオッケーです。ログアウト時にトークン情報が残ったままのため、エラー発生
ログアウトは、「有効なトークン情報がなくなる」なので、先ほどのコードにトークン情報の有無を確認するテストコードを追記しました。
describe "DELETE /v1/auth/user/sign_out" do subject { delete(destroy_v1_user_session_path, headers: headers) } context "トレーナーログアウト時" do let(:user) { create(:user) } let(:headers) { user.create_new_auth_token } it "トークンを無くし、ログアウトできる" do subject + expect(user.tokens).to be_blank expect(response).to have_http_status(200) end end endエラー内容
Failure/Error: expect(trainer.tokens).to be_blank expected `{"LT4SdlN2czyzNnwTfLGjTw"=>{"expiry"=>1596957557, "token"=>"$2a$10$BgZ4YItos1hQRTp4y1JvZ.mIsreaIxD1NC3ckRk0euxsk8IBkoM7K", "updated_at"=>"2020-07-26 07:19:17 UTC"}}.blank?` to return true, got falseトークン情報が残ったままとのエラーです。
ログアウトに必要な情報を user に入れ、ログアウトの処理はできても、user の値は更新されないので残ったままになっています。
user の値を更新するためには、user.reload.token
と記述してあげる必要があります。describe "DELETE /v1/auth/user/sign_out" do subject { delete(destroy_v1_user_session_path, headers: headers) } context "トレーナーログアウト時" do let(:user) { create(:user) } let(:headers) { user.create_new_auth_token } it "トークンを無くし、ログアウトできる" do subject expect(user.reload.tokens).to be_blank expect(response).to have_http_status(200) end end end以上の内容にすれば、ログアウト後の user の値が更新されるため、user にトークン情報がなくなります。
- 投稿日:2020-07-27T08:46:31+09:00
[Rails]find_eachが無限ループして本番環境のメモリを食いつぶした話
ActiveRecordにある便利メソッド
find_each
実装の仕方が良くなくて無限ループしてしまい、本番環境でOOM killerによって強制停止させられるという事象が発生したのでその話について書きます。
※ この記事に登場するテーブルや実装などはすべて記事用にカスタマイズしていますfind_eachとは
find_eachは何をしてくれるかというと、大量のデータを一度に取得してループするのではなく決まった単位(デフォルト1,000件)ごとに取得してループしてくれます。
大量データを扱うときに一括で取得してしまうと大量のメモリを使っていしまうのですが、find_eachを使って分割して取得することで少ないメモリで処理することができます。言葉で書いてもわかりづらいですね。下記が実行例です。
# userが1万人いる場合 pry(main)> User.all.count (1.1ms) SELECT COUNT(*) FROM `users` => 10000 # eachを使うと一括で1万件取得される pry(main)> User.all.each {|user| p user.id} User Load (4.5ms) SELECT `users`.* FROM `users` 1 2 3 ... 10000 # find_eachを使うと1,000件ずつ取得される [8] pry(main)> User.all.find_each {|user| p user.id} User Load (3.9ms) SELECT `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT 1000 1 2 3 ... 1000 User Load (0.8ms) SELECT `users`.* FROM `users` WHERE `users`.`id` > 1000 ORDER BY `users`.`id` ASC LIMIT 1000 1001 1002 1003 ... 2000 User Load (0.8ms) SELECT `users`.* FROM `users` WHERE `users`.`id` > 2000 ORDER BY `users`.`id` ASC LIMIT 1000 2001 ... 10000詳細はRailsガイドをご覧ください。
https://railsguides.jp/active_record_querying.html#find-eachfind_eachが無限ループ!!
便利メソッドfind_eachですが、最初に書いたとおり実装をミスって無限ループさせてしまいました。
無限ループになった実装を説明する前に、そもそもfind_eachはどのような仕組みで動いているのか確認します。find_eachの仕組み
最初に載せた実行例を使ってどのように動いているのか確認します。
一番最初に発行されるSQLを見てみましょう。
SELECT `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT 1000limit 1000を指定して1000件取得しています。
ここで注目すべきはPRIMARY KEY(id)の昇順に並べているところです。それでは次の1000件はどのように取得しているのでしょうか?
SELECT `users`.* FROM `users` WHERE `users`.`id` > 1000 ORDER BY `users`.`id` ASC LIMIT 1000SQLを使って次の1000件を取得する場合はLIMITとOFFSETを使う事がよくありますが、今回のSQLにはOFFSETは使われていません。
代わりにwhere句にusers.id > 1000
という条件が増えていることがわかります。
users.id > 1000
の1000は最初に取得した1000件の最後のidが指定されています。
今回のデータはidの昇順に並んでいるため、最後のidより大きいデータを取得するという意味のusers.id > 1000
を条件に指定することでOFFSETを使わずに次の1000件を取得しています。無限ループになる実装
無限ループが発生したfind_eachは下記のように実装されていました。
何が起きるのでしょうか?# users.idとbooks.titleしか使わないのでselectで必要なデータのみ取得する Book.joins(:user).select('users.id, books.title').find_each do |book| p "user_id: #{book.id}, title: #{book.title}" end最初は下記のSQLが発行されます。
SELECT users.id, books.title FROM `books` INNER JOIN `users` ON `users`.`id` = `books`.`user_id` ORDER BY `books`.`id` ASC LIMIT 10001件目のSQLは特に問題ありません。
それでは次の1000件を取得するSQLはどうなるのでしょうか?SELECT users.id, books.title FROM `books` INNER JOIN `users` ON `users`.`id` = `books`.`user_id` WHERE `books`.`id` > 1000 ORDER BY `books`.`id` ASC LIMIT 1000
books.id > 1000
とい条件が追加されています。条件の1000は最初に取得した1000件の最後のデータのidです。
SQLだけを見ていると気づきづらいですが、今回のSQLで取得しているidはbooks.id
ではなくusers.id
です。
そのため、books.id > 1000
に設定されている1000は最後のデータのusers.idが指定されています。このSQLではbooks.idの昇順になっており、users.idの順序は特に制御されていません。
そのため、次の1000件目の最後のデータがbooks.id: 2000, users.id: 1
ということもありえます。
この場合、次に発行されるSQLは下記のようになります。SELECT users.id, books.title FROM `books` INNER JOIN `users` ON `users`.`id` = `books`.`user_id` WHERE `books`.`id` > 1 ORDER BY `books`.`id` ASC LIMIT 1000条件が
books.id > 1
となってしまい、1つ前のSQL(books.id > 1000
)より前のデータを取得してしまいます。
このようにbooks.idの条件に順序が制御されていないusers.idが入ることで、取得するデータが前後してしまい、最悪の場合何度も同じデータを取得してしまい無限ループしてしまいます。この問題の厄介なところは常に無限ループになるわけではなく、データによっては
books.id > #{最後のusers.id}
がたまたまいい感じに指定されてそれっぽく完了してしまうこともあることです。
その場合、エラーにはならないけどデータが微妙におかしいという気づきづらいバグになってしまうので、無限ループになってくれたほうがマシかもしれません。修正方法
上記の例の場合であれば、selectで取得カラムを絞らなくするとbooks.idも取得するようになるので正しく動作するようになります。
selectで取得カラムを絞る場合でも下記のようにbooks.idもきちんと取得するようにすれば正しく動作します。Book.joins(:user).select('books.id AS id, users.id AS user_id, books.title').find_each do |book| p "user_id: #{book.user_id}, title: #{book.title}" end上記の通り修正すれば修正完了ですが、今回の問題は自動テストがなかったことだと思っています。
該当の処理を通るテストはあったのですが、find_eachを2ループ以上するテストは書いていませんでした。
テストがあれば、無限ループするか結果がおかしくなるのでバグに気づけていた可能性が高いです。
これをきっかけにfind_eachが2ループ以上するテストも追加しました。まとめ
今回のバグはfind_eachの仕組みを正しく理解していたとしても、コードレビューなど机上確認だけで気づくのは難しいと思います。
また、1000件以上になることが稀な処理であり、1000件という単位もただのプログラム上の都合なので、ブラックボックスな動作テストでも気づかれずにしばらく潜在バグとして潜んでいました。これに事前に気づくにはどうすればよかったのかと考えると、ホワイトボックステストでfind_eachが2ループするテストをするしかないと思いました。
ホワイトボックステストを手動でワンタイム実行してももったいないので、きちんと自動テストを書いて継続的に検証できるようにしておくとよいですね。
- 投稿日:2020-07-27T02:13:37+09:00
【rails】activehashについて
Active Hashとは
ハッシュ形式の値をActive Recordと同じように操作できるようにするgem
Relationも貼れるので便利基本的な使い方
以下のような書き方ができる
app/models/plan.rbclass Plan < ActiveHash::Base self.data = [ {id: 1, name: "free"}, {id: 2, name: "silver"}, {id: 3, name: "gold"}, ] end class Plan < ActiveHash::Base self.data = [ {id => 1, name => "free"}, {id => 2, name => "silver"}, {id => 3, name => "gold"}, ] end class Plan < ActiveHash::Base fields :name add id: 1, name: "free" add id: 2, name: "silver" add id: 3, name: "gold" endターミナルpry(main)>Plan.first => #<Plan:0x00007ffd3d2c43f8 @attributes={:id=>1, :name=>"free"}>
relationを貼りたいモデルに以下を記載すればアソシエーションを利用してデータを操作できる。
ActiveHashのモデル側には特に追記することはないextend ActiveHash::Associations::ActiveRecordExtensions belongs_to_active_hash :ActiveHashのモデル名参考
https://qiita.com/DON4024/items/78edb7a309ee96766952
https://qiita.com/Toman1223/items/8633142312bfa886d50b
- 投稿日:2020-07-27T01:40:05+09:00
Railsアプリで画像の保存先をS3に変更する。その2
はじめに
前回の記事からの続きです。
安全にAWSのキーを扱えるようにする
AWSキーの漏洩を防ぐため、キーの内容は環境変数に設定します。
環境変数が分からない人はググって調べてみましょう!AWSのキーの設定
carrierwave.rbのなかに[:access_key_id]や[:secret_access_key]といった記載がありました。
ここには予め設定したキーが入り、Rails5.2では「credentials.yml.enc」というファイルで管理されます。それではcredentials.yml.encをエディタで開いてみましょう。
以下のように暗号化された文字列が表示されると思います。
これをターミナルからVSCodeを起動できるよう設定を行います。
VSCodeで、「Command + Shift + P」を同時に押してコマンドパレットを開きます。
続いて、「shell」と入力しましょう。
メニューに「PATH内に'code'コマンドをインストールします」という項目が表示されるので、それをクリックします。
この操作を行うことで、ターミナルから「code」と打つことでVSCodeを起動できるようになります。それではターミナルから以下のコマンドを実行しましょう。
復号化されたcredentials.yml.encがVSCodeで表示され、編集可能となるはずです。% EDITOR='code --wait' rails credentials:editAWSのaccess_key_idとsecret_access_keyを以下のように編集しましょう。
master.keyの設定
credentials.yml.encはmaster.keyというファイルで復号化を行います。
しかし、本番環境にmaster.keyを配置することはセキュリティ上問題があります。
そのため、本番環境の環境変数にmaster.keyの中身を設定しましょう。EC2インスタンスにログインし、環境変数の設定を行うファイルを開きます。
sudo vim /etc/environmentローカル開発環境で「config/master.key」の値をコピーして、本番環境のRAILS_MASTER_KEYに設定します。
RAILS_MASTER_KEY='master.keyの値'これで環境変数が設定できたはずなので、EC2インスタンスにログインし直して以下のコマンドで環境変数を確認しましょう。
env | grep RAILS_MASTER_KEYまとめ
環境変数を参照する流れをまとめますと以下のようになります。
1.credentials.yml.encをローカル環境のmaster.keyで復号する
2.credentials.yml.encを編集し、access_key_idとsecret_access_keyを設定する。
3.本番環境にデプロイする
4.master.keyの内容を本番環境の環境変数に設定する。
5.本番環境のcredentials.yml.encが環境変数を用いて復号可能となる。前回の記事と上記の設定を行えば、S3に画像をアップロード出来るようになるはずです!多分!以上!
- 投稿日:2020-07-27T00:05:15+09:00
[Rails]Railsのバージョンを5.0→5.2に上げてみた
やりたいこと
Rails5.0系からRails5.2系にバージョンを上げたい。(Rails5.2から使えるようになったActive Storageを使いたかった。)
この記事の趣旨は、Rails5.0系からRails5.2系にバージョンを上げるために必要な手順とその際に発生したエラー対応をご紹介したい(そしてActive Storage使いたい)というものです。
修正(2020/07/27)
伊藤さんご本人からコメントいただき、
bootsnap gem
を追加する方法に変更いたしました。
詳しくはこの記事のコメントをご確認ください?♂️環境
Ruby 2.5.1
Rails 5.0.7.2手順
伊藤さんのQiita記事を大いに参考にさせていただきました。
永久保存版!?伊藤さん式・Railsアプリのアップグレード手順基本的には伊藤さんの記事を見ていただくのがわかりやすいです(この記事の意味)。
ただ、「とりあえず早いとこバージョン上げたい!!」という方も少なからずいらっしゃるかと思うので、邪道的な形で見ていただけると幸いです。また、本来はテストまでカバーすべきですが、今回は目的がActive Storageを使うことなので、そちらに関しては割愛します。
1. Rails以外のgemをバージョンアップする
Rails本体のバージョンを先に上げてしまうと、DeviseやCarrierwaveのような周辺のgemが最新のRailsに対応しておらず、思いがけないエラーが起きるかもしれません。
はい。まさに起きました。笑
1-1. developmentとtestグループのgemを先にアップデートする
terminal# 該当のアプリのディレクトリで実行 $ bundle update -g development -g test1-2. トラブルが起きやすそうなgemを1つずつアップデートする
bundle outdated
コマンドを実行すると、最新でないgemが一覧表示されます。
ただ、そこまでgemの数が多くない場合は、一気にアップデートしてしまってもいいかもしれません。1つずつアップデートする場合は、
bundle update
の後ろにgem名を指定します。terminal# deviseだけをアップデートしたい時 $ bundle update devise1-3. その他のgemをまとめてアップデートする
gem名を指定せず、
bundle update
です。
※なお、このタイミングではRailsのバージョンは変えないでください(元のバージョン指定のままにしておく)。Railsのバージョンアップは別途行います。Gemfile# Railsのバージョン指定は元のままにしておく gem 'rails', '~> 5.0.7', '>= 5.0.7.2'Railsのバージョン指定がされていることを確認したら、
bundle update
terminal# gemをまとめてアップデートする $ bundle update2. Railsのバージョンを上げる
GemfileでRailsのバージョン指定を変更して、
bundle update rails
です。Gemfile# gem 'rails', '~> 5.0.7', '>= 5.0.7.2' gem 'rails', '~> 5.2.4', '>= 5.2.4.2'terminal$ bundle update rails3. rails app:updateタスクを実行する
次にrails app:updateタスクを実行します。
このタスクを実行すると、新しいバージョンで必要になる新しいファイル作成や、既存ファイルの変更を対話形式で行うことができます。terminal$ rails app:update conflict config/boot.rb Overwrite config/boot.rb? (enter "h" for help) [Ynaqdhm]上記のように、コンフリクトが起きるファイルの扱いをどうするかを一つずつ確認していく作業です。
Y/n/a/q/d/hのいずれかのキーで回答します。Y - Yes。上書き実行 n - No。上書きしない a - All。このファイル以降の全ファイルを上書き q - Quit。処理中断 d - Diff。新旧ファイルのdiffを表示 h - Help。入力する各キーの意味を表示「これ一個ずつ確認するの面倒…まとめてやっていいんじゃ?」
はい、僕もそう思って、
a
= allを実行しました。
するとroutes.rb
がまっさらに生まれ変わりました(白日か)。
routes.rb
だけはしっかり確認しましょう!というよりn
にしましょう!!伊藤さんもこうおっしゃっています。
僕はd = diffを確認した上で、Yかnを入力することが多いです。
(でも、routes.rb以外はほとんどYを入力しているかもしれない)4. 動作確認(
rails s
が起動するか)他にもテストコードや自分の目で見て確認も必要ですが、今回は
rails s
(とりあえず開発環境でサーバー起動させる)を目指します。4-1. エラー①
意気揚々と
rails s
したところまずはこちらのエラーから。
require': cannot load such file -- bootsnap/setup (LoadError)
とのエラーが。terminal$ rails s Traceback (most recent call last): 3: from bin/rails:3:in `<main>' 2: from bin/rails:3:in `require_relative' 1: from /myapp/config/boot.rb:4:in `<top (required)>' ~~~config/boot.rb:4:in `require': cannot load such file -- bootsnap/setup (LoadError)こちらの方法で対応できました。変更箇所は2箇所(ファイル)。
Gemfile# 全部の環境に適用させたいので、グループの中には入れない gem 'bootsnap', require: falseconfig/initializers/new_framework_defaults.rb~ # この行↓をコメントアウト # ActiveSupport.halt_callback_chains_on_return_false = false ~4-2. エラー②
「さあ、今度こそサーバー起動だ!」と思って
rails s
したらまたもエラーが。
<top (required)>': undefined method `halt_callback_chains_on_return_false=' for ActiveSupport:Module (NoMethodError)
terminal=> Booting Puma => Rails 5.2.4.3 application starting in development => Run `rails server -h` for more startup options Exiting Traceback (most recent call last): ~~~/config/initializers/new_framework_defaults.rb:23:in `<top (required)>': undefined method `halt_callback_chains_on_return_false=' for ActiveSupport:Module (NoMethodError)こちらで対応できました。
config/initializers/new_framework_defaults.rb~ # この行↓コメントアウト # Rails.application.config.action_controller.raise_on_unfiltered_parameters = true ~必読の記事
今回僕が遭遇したエラーは、伊藤さんがまさにおっしゃっている部分なので、この記事は読んで理解しておくと今後に役立つと思います。
Railsのバージョンが上がると、従来の挙動とは異なる、新しい挙動が導入される場合があります。
バージョンアップ後はすべて新しい挙動に合わせられるのが理想的ですが、場合によっては一部の挙動を古いRailsに合わせないといけないかもしれません。こうした挙動の変更はload_defaultsやnew_framework_defaults_x_x.rbで行います。
load_defaultsとnew_framework_defaults_x_x.rbの関係については以下の記事で詳しく説明しているので、こちらを読んで適切に設定を変更してください。
config.load_defaultsとnew_framework_defaults_x_x.rbの関係を詳しく調べてみた - Qiita
Railsのバージョンアップは完了
これでRailsのバージョンアップは完了です。
上記手順で実行してもうまくいかない時は、サーバーの再起動(ctrl + c
で終了、rails s
で起動)を試してみてください。5. 環境変数周りのファイルってどうなるの?
環境変数を定義するファイルは、Rails5.0系では
secrets.yml
でしたが、Rails5.2系以降はcredentials.yml.enc
とmaster.key
を使用するのが一般的です。5-0. 「あれ?credentialsもmasterキーもなくない??」
Railsのバージョンアップをすれば勝手に作られるものだと思っていましたが、そんな美味しい話はありませんでした。
そもそもmaster.key
はrails new
時に作成されるもののはずなので、当たり前といえば当たり前ですが…5-1. 結論:
secrets.yml
のままで良い特に環境変数ファイルはいじることなく動作しました。笑