Ruby on Railsを勉強中に遭遇した問題(1)
PHP+MySQLを勉強しようとしていたんだけど、何となくRuby on Railsが気になって、こちらの勉強を先に始めることにしました。
早速、テキストとして「Ruby on Rails 6 超入門」を購入して勉強を始めました。
テキストに従ってやっていくと、テキストには書かれていない問題にいろいろ遭遇しました。
原因は、導入した Ruby がバージョン3.1、Rails が バージョン7.0 によるところが大きいようで、特に Rails はいろいろ変更されているようです。
Ruby on Rails 7の主要な新機能・機能追加・変更点 - Qiita
Rails 7では、JavaScriptフロントエンドの大幅な刷新、CSS BundlingによるTailwind CSSやPostCSSのサポートを含めた、メジャーバージョンアップグレードにふさわしい機能強化が行われています。
ちなみに、導入したバージョンは以下のものです。
C:\Windows\System32>ruby -v ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x64-mingw-ucrt] C:\Windows\System32>rails -v Rails 7.0.3.1
ここでは、遭遇した問題について、内容と対応を記録したいと思います。
Railsアプリケーションの作成
rails aborted! TZInfo::DataSourceNotFound
「rails new アプリケーション名」でアプリケーションを作成しようとすると、以下のようなエラーが出ます。
Webでググったところ、以下の情報がありました。
ruby - rails new を実行した際に、rails aborted !というエラーが出て解決できません。 - スタック・オーバーフロー
Ruby Istallerの64bit版は、3.0系まではmingw64でしたが、3.1系からはucrt64に変更になりました。
(中略)
ucrt64版は対象では無いと判断されます。現在の所、Bundlerにucrt64版を指定する
platform
に渡すオプションは存在しません。(中略)
しかし、この
platform
の指定ではucrt64版は対象とはならないため、tzinfo-dataが読み込まれず、railsの実行に失敗する状況になっていました。根本的に修正されるにはBundler側がucrt64版に対応することとRails側がucrt64版でもtzinfo-dataを対象とするように初期のGemfileを用意するようにすることの二つが必要です。
対応として、提示されている解決策の「Gemfile で tzinfo-data を読み込むようにする。」を行いました。
まず、以下の「template.rb」を作成します。
data = File.read('Gemfile')
data.sub!(/^.*gem "tzinfo-data".*$/, 'install_if(-> { RUBY_PLATFORM =~ /mingw|mswin|java/ }) { gem "tzinfo-data" }')
File.write('Gemfile', data)
これで、「rails new アプリケーション名 -m template.rb」を実行すると、TZInfo のエラーは出なくなりました。
run bundle install NameError: uninitialized constant Gem::Source
次に出ていたのは、bundle 時のエラーです。
rails new自体は最後まで処理された感じではあるのですが、以下のエラーが途中に出力されています。
run bundle install [14668, #<Thread:0x0000025031c757a8 run>, #<NameError: uninitialized constant Gem::Source (defined?(@source) && @source) || Gem::Source::Installed.new
これも Webをググると、以下の情報がありました。
【Docker】NameError: uninitialized constant Gem::Source 解消法【Rails】 - Qiita
どうやらBundlerのバージョンが
2.3.7
だとNameError: uninitialized constant Gem::Source
が発生するようです。
ということで、Bundlerのバージョンを確認しました。
c:\Data\Web_study\Rails>bundler -v Bundler version 2.3.7
ビンゴです。
早速 Bundler のバージョンをアップしました。
c:\Data\Web_study\Rails>gem install bundler Fetching bundler-2.3.20.gem Successfully installed bundler-2.3.20 Parsing documentation for bundler-2.3.20 Installing ri documentation for bundler-2.3.20 Done installing documentation for bundler after 1 seconds 1 gem installed c:\Data\Web_study\Rails>bundler -v Bundler version 2.3.20
この状態で「rails new アプリケーション名 -m template.rb」を実行すると、次のように問題なくBundle処理が始まり、Railsアプリケーションが作成されました。
run bundle install Fetching gem metadata from https://rubygems.org/........... Resolving dependencies..... ・・・ Installing tzinfo-data 1.2022.2 Bundle complete! 15 Gemfile dependencies, 75 gems now installed.
Rails Serverを立ち上げてアクセスすると、次のサンプル・ページが表示されました。
コントローラーとビュー
assets scss が作成されない
rails generate controllerコマンドで、コントローラーを作成した時、以下のメッセージが出力されます。
c:\Data\Web_study\Rails\RailsApp>rails generate controller hello create app/controllers/hello_controller.rb invoke erb create app/views/hello invoke test_unit create test/controllers/hello_controller_test.rb invoke helper create app/helpers/hello_helper.rb invoke test_unit
見たとおり、assets scss が有りません。
テキストで指示されている .scssファイルは、自分で作成することにしました。
cannot load such file -- sassc
テンプレートを使用するために、application.html.erb を使用したところ、以下のメッセージが表示されました。
これも Webをググると、解決方法を示されている奇特な方がおられました。
rails 7.00における "cannot load such file --sassc"の解決法 - Qiita
コメントアウトを削除して、bundle installをすることで解決することができます。
rails7.00以前はこのgemが環境構築の際に自動でinstallされていましたが、7.00以降では標準でインストールされないようです.
とのことなので、アプリケーションのフォルダーにある Gemfile を変更し、コメントを外しました。
45 # Use Sass to process CSS 46 # gem "sassc-rails" ↓ 45 # Use Sass to process CSS 46 gem "sassc-rails"
そして、bundle install し直します。
c:\Data\Web_study\Rails\RailsApp>bundle install ・・・ Using sassc 2.4.0 ・・・ Bundle complete! 16 Gemfile dependencies, 79 gems now installed.
rails server を再度立ち上げてアクセスしたところ、エラーにならずに表示されました。
hello.scss がうまく適用されない
ところが、hello.scss で設定したスタイルになりません。
分かりやすいように、h1 と p で以下のように色を分けてみました。
body { color: darkred; font-size: 28px; } h1 { color: darkblue; margin: 25px 0px; }
しかし、ヘッダーの方は色が変わったのですが、パラグラフの方は色が変わりません。
デベロッパー・ツールで確認すると、_reboot.scss で定義した方が application... で定義したものより先に有効になっています。
テキストでは、<head> ~ </head>内に、<link rel="stylesheet" href="https:// ... bootstrap.css> のタグを追加するとしか書かれていません。
しかし、書き方の順番が問題です。
そこで、以下のように、<%= stylesheet_link_tag ...>の上にくるように変更しました。
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.css"> <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> <%= javascript_importmap_tags %>
これでうまくスタイルが適用されました。
デベロッパー・ツールで見ても、application... で指定したものが有効になっています。
この辺は、基本中の基本的なことかもしれません。(^ ^);
フォームの送信ができない
テキスト通りに index.html.erb や hello_contrller.rb や routes.rb を修正したはずなのに、フォームの入力画面からテキストを入力して「送信」ボタンを押すとエラーになります。
しかも、テキストで示されているような「ActionController::InvalidAuthenticityToken」というエラーではありません。
ブラウザー「Google Chrome:バージョン: 106.0.5249.119(Official Build) (64 ビット)」のデベロッパー・ツールで見ると、コンソールにエラーが1件(Form responses must redirect to another location)と警告が2件表示されました。
そこで、「Form responses must redirect to another location」でググってみると、「Turboの動作をオフにする」という情報が、以下のページの引用部分に有りました。
https://factor.xseed.link/2022/04/01/post-17888/#outline__2
Turboの動作をオフにする方法は、以下のページに載っています。
http://Turbo Drive をリンク/フォーム単位で無効化する
formタグでTurboの動作をオフにする
早速、以下の赤字ように formタグに追記してみました。
<form data-turbo="false" method="POST" action="/hello/index">
これで正しく?動いて、テキストと同じエラー画面が表示されました。
フォームヘルパーでTurboの動作をオフにする
ところが、フォームヘルパーを使用すると、やはり Turbo の動作が入ってエラーになります。
理由は、テキストにある form_tag を使って Turbo オフを追記してみると、以下のような formタグが生成されてしまうからです。
<%= form_tag(controller: "hello", action: "index", data: {turbo: false}) do %> ↓ <form action="/hello/index?data%5Bturbo%5D=false" accept-charset="UTF-8" method="post">
そこで、form_tagヘルパーメソッドは非推奨なので、後継である form_withヘルパーメソッドに変更してみました。
<%= form_with(controller: "hello", action: "index", data: {turbo: false}) do %> ↓ <form data-turbo="false" action="/hello/index" accept-charset="UTF-8" method="post">
今度は、formタグに「data-turbo="false"」が作成されており、正しく動作することができました。
javascript_pack_tagがエラーになる
レイアウトを作成するとのことで、hello.html.erb を作成しました。
ところが、テキスト通りに入力し実行すると、javascript_pack_tag が NoMethodError になります。
そこで、もともと application.html.erb で記述されていた以下のものに変更しました。
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %> ↓ <%= javascript_importmap_tags %>
javascript_importmap_tags では、以下のタグが生成されます。
<script src="/assets/es-module-shims.min-d89e73202ec09dede55fb74115af9c5f9f2bb965433de1c2446e1faa6dac2470.js" async="async" data-turbo-track="reload"></script> <script type="module">import "application"</script>
因みに、javascript_pack_tag は、Webpacker でビルドしたスクリプトを読み込む指定のようですが、Webpacker 自体よく理解できていないので、これ以上の深追いはあきらめました。
circular argument reference エラーになる
メッセージ・ボードを作成するとのことで、msgboard_contoroller.rb を作成しました。
実行したところ、circular argument reference のエラーになります。
Webをググると、やっぱりヒットしました。
以前は、warning だったようです。
ruby2.2.0ではメソッドの引数のデフォルト値に同じ名前の変数を使えない - Qiita
以下のページのように、キーワード引数に括弧 ( ) を付けることで解消されました。
【rails備忘録】エラー:circular argument reference (Ruby on Rails 6 超入門) | マサのライフワーク
以上、Ruby on Rails を勉強していく中で、いろいろ経験することができました。
取りあえず ControllerとView の第2章まで終わったので、続きがあれば別のページに載せていきたいと思います。