初めまして、ゆん♂です!
不動産業界に激震を走らせるためのアプリを作ってます!
どうせ作るなら最新の環境で作りたい!ということで Rails6系
でアプリ制作してます。
が! Rails5系
と Rails6系
では大きく仕様が異なっており、表題のような簡単なことでも超絶つまづいてしまいました。
解決してみたら何のことはなかったんですが、僕はこれだけで丸1日溶けました…。
なので同じ轍を踏まないよう、僕の試行錯誤の軌跡をここに残しておきます。
長ったらしい話はいいからさっさと結果だけよこせや、って方はこちらへどうぞ!
開発環境
言語: Ruby2.6.6
フレームワーク: Rails6.0.3.4
データベース: MySQL(ローカル)
IDE: VScode
Rails6ってなんかカッコイイ!!
これは Rails6
を採択した理由です。マジです。
Rails6
って何か響きだけでカッコ良くないですか!?
しかも5よりも6のほうが新しいし、古いバージョンで作って早々バージョンアップデートとか必要になったら二度手間!
(↑これは多分正しい、、、はず)
という安直な理由で Rails6
を採択しました。
このあと地獄を見るとも知らずに、、、
Materialize.cssのDatepickerオシャレ!!
ちょっと見てくださいコレ。
めちゃくちゃオシャレじゃないですか??
CSS
全く書かずにこんなUIが実現できるなんて便利な世の中ですよねほんと☺️
で、このドキュメントには
「カレンダー表示させたい inputタグ
に datepicker
というクラス名を付けてな」
「あとは JavaScript
か jQuery
でちょちょいと書いたら終わりやで」
と書いてあります。オージーザス、神よありがとう🙏
gem じゃなくて webpacker!!
Datepicker
を使うには jQuery
を入れておいた方が良さそうです。
Rails5系
だと gem
でインストールして CSS
や JS
で読み込ませてねー的な記事がたくさん出てくるのですが、Rails6系
では JavaScript系のパッケージ機能を gem
ではなく webpacker
で管理するようになったそうです!
Webpackerとは、 Webpackを使用してRuby on Rails上でJavaScript開発をするために必要な一連のまとまりを、標準で実装することができるgemパッケージ です。 Rails6.0より、webpackerが標準実装になりました。
なんてこったパンナコッタ!!
オーマイゴッドファーザー降臨!よいしょ!
こりゃ便利!!、、、、、なのでしょうか🤔??
この辺り実はメリデメがよく分かっていません。
んー、あいまいみーまいん🙁
まぁ正確な理解は置いておいて、Rails6 jQuery
で調べると必ずと言っていいほど webpacker
で管理しましょうねーという記事が出てきます。
というかそんな記事しかありません!
(↑それ自体は多分正しい)
併せて jquery-ui-dist
なるものもインストールする必要があるようです。
以下、参考にした記事
Rails6でjQueryの導入方法
【Rails6】jQueryがなかなか使い始められない人へ
【Rails6】Webpackerを用いてjQueryをインストールする手順を簡単にまとめてみた
Rails 6:webpackerを介してjquery-uiを追加する方法は?
実はこの時すでに術中にハマってました。
js系のパッ毛0時は必ず webpacker
で管理しなければならないと思い込んでいたのです。
そのため、 rails6 webpacker datepicker
とか webpacker jquery-ui-dist
などと調べていたため、余計にドツボにハマる結果となりました。
パッ毛0時
て何やねん、パッケージ
やろがい。
丸1日かけてやったこと(間違い)
リアルに丸1日ハマり倒した内容を簡潔に書いていきます。
間違ってもこの手順を踏まないでください。
あくまでも同じ過ちを犯さないで欲しいがためのメモです。
これは誤った手順です!
① Yarnで jQuery
と jquery-ui-dist
をインストール
$ yarn add jquery
$ yarn add jquery-ui-dist
↑ターミナルでこのコマンドを実行しました。
② jQuery
と jquery-ui-dist
を有効化
const { environment } = require('@rails/webpacker')
// 追加ここから //////////////////////////////////////////
const webpack = require('webpack')
environment.plugins.prepend('Provide',
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
})
);
const aliasConfig = {
'jquery': 'jquery-ui-dist/external/jquery/jquery.js',
'jquery-ui': 'jquery-ui-dist/jquery-ui.js'
};
environment.config.set('resolve.alias', aliasConfig);
// 追加ここまで //////////////////////////////////////////
module.exports = environment
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
// 追加ここから //////////////////////////////////////////
global.$ = require("jquery")
require("jquery")
require("jquery-ui")
// 追加ここまで //////////////////////////////////////////
<!DOCTYPE html>
<html>
<head>
<title>ReTECH</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<!-- Compiled and minified JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<!-- Let browser know website is optimized for mobile -->
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<!-- Make FontAwesome available -->
<script src="https://kit.fontawesome.com/xxxxxxxxxxx.js" crossorigin="anonymous"></script>
<%= favicon_link_tag 'favicon.ico' %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= stylesheet_link_tag '//ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/le-frog/jquery-ui.min.css' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
<body>
<%= yield %>
</body>
</html>
↑ 各ファイルにこのような記述を追加しました。
※ app/views/layouts/application.html.erb
に関しては Materialize.css
をCDN読み込みしてたりするので丸々掲載しました。<script src="https://kit.fontawesome.com/xxxxxxxxxxx.js"
の xxxxxxxxxxx.js
の部分は各自アカウントにより異なります。FontAwesome
アカウント発行を自分で発行して適切な文字に置き換えてください。
参照: Rails 6: How to add jquery-ui through webpacker?
参照: FontAwesome6 無料登録
③ datepicker
をフォームに適用してみる
$(document).ready(function(){
$('.datepicker').datepicker();
});
↑datepicker用jsファイルを定義
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
global.$ = require("jquery")
require("jquery")
require("jquery-ui")
// 追加ここから //////////////////////////////////////////
require("../modules/datepicker")
// 追加ここまで //////////////////////////////////////////
↑作ったdatepicker定義ファイルの読み込み
<div class="input-field">
<%= f.label :birthday %><br />
<%= f.text_field :birthday, required: true, class: 'datepicker' %>
</div>
↑誕生日入力フォームに datepicker
というクラス名を付与
出来上がったものがこちらです☺️
おい!
昔のiPhoneかよ!
一瞬電卓に見えたわ!
マテリアルの「マ」の字もないな!
作りたいのはこっち!!
どれどれ、、、
電卓かて!!
たぶん原因はこんな感じ
恐らく原因は CDNで Materialize.css
を先に呼び出してしまい、そのあと webpacker
の設定が読み込まれるため デフォルトの datepicker
のUIで上書きされてしまっているのかなと推測しました。
ダメ元で Materialize.css
のCDN呼び出しの記述をファイル後尾に移動したり、CDNではなく CSSファイル
と JSファイル
をダウンロードしてきて配置したりしました。
が、やはりダメ、、、
今までやったことは一応 Github
でプルリク作って、もう一度やり直すことを決めました。。。
そして色んな試行錯誤を重ねた結果、こんな境地にたどり着いたのです。
jQuery
もCDNで呼び出せちゃったりしたりするかもなんじゃない?
そうです、何も webpacker
で管理せず、Materialize.css
と同じようにCDNで呼び出しちゃえばいいのでは?
そうすれば先に jQuery
呼び出して、後から Materialize.css
を呼び出せる、、、UIを上書きされることもないはず!!
ということでやってみた(これが正解)
<!DOCTYPE html>
<html>
<head>
<title>ReTECH</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<!-- Expressly read CDN to make jQuery available before make Materialize-UI available -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<!-- Compiled and minified JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<!-- Let browser know website is optimized for mobile -->
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<!-- Make FontAwesome available -->
<script src="https://kit.fontawesome.com/xxxxxxxxxxxx.js" crossorigin="anonymous"></script>
<%= favicon_link_tag 'favicon.ico' %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
<body>
<%= yield %>
</body>
</html>
↑<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
という記述で jQuery
を先に読み込み、そのあとに Materialize.css
のCDNを読み込んでいる。
$('document').ready(function() {
$('.datepicker').datepicker();
})
↑datepicker定義
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
// 追加ここから //////////////////////////////////////////
require("../modules/datepicker")
// 追加ここまで //////////////////////////////////////////
↑datepicker読み込み
<div class="input-field">
<%= f.label :birthday %><br />
<%= f.text_field :birthday, required: true, class: 'datepicker' %>
</div>
↑誕生日入力フォームに datepicker
というクラス名を付与
出来上がったものがこちらです😎
完璧!!!
以上、長文にお付き合いいただきありがとうございました🙇♂️