はじめに
本記事はプログラミング初心者が、railsの学習を進めながら、躓いた部分、解決した箇所、またそれらの解決方法を備忘録も兼ねてまとめているものです。
最初はprogate。そのあと、「現場で使える RubyonRails5 速習実践ガイド」(通称)「現場Rails」を参考に進めていきました。
そのため、記事の内容には誤りがある可能性があることをご理解ください。
誤りがあればお手数ですが、ご指摘いただければと思います。よろしくお願いします。
環境
Ruby 3.1.2
Rails 7.0.3.1
問題のエラー
バリデーションが実行された後に、jsが機能しなくなってしまった。
本来ならば、上記の二枚のようになり、判定を開始するボタンが押せるのですが、押して、バリデーションが実行された後、
このように、ボタンが出てきません(jsが反映されていない。)
解決策
どうやら、turboにヒントが隠されているようです。最初のコードを見てみましょう。
document.addEventListener("turbo:load", function() {
var allowCheckbox = document.getElementById("check");
var checkbutton = document.getElementById("link3");
allowCheckbox.addEventListener("change", function(event) {
if (event.target.checked) {
checkbutton.disabled = false;
} else {
checkbutton.disabled = true;
}
}, false);
})
一行目のturbo
は、ページをリロードした時に、もう一度jsが反映されるように記載しているものです。
しかしながら、バリデーションが実行された後は、コントローラーを見てみると、
class UsersController < ApplicationController
def show
@user = User.find(params[:id])
end
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
redirect_to @user, notice: "判定が正常に実行されました。"
else
render :new, status: :unprocessable_entity
end
end
private
def user_params
params.require(:user).permit(:name, :sex, :age, :hemo, :feti, :sterone, :agreement)
end
end
はい、新規登録画面にいくのに、render
になっています。
ここがポイントのようで、renderの場合でも、turboを使ってjsが反映できるようにすることができるようです。それが、以下
document.addEventListener("turbo:render", function() {
上記のようにturbo:load
の他にturbo:render
を付け足すことで、renderされても、jsが反映されるようです。
出来上がったコードがこちら
document.addEventListener("turbo:load", function() {
var allowCheckbox = document.getElementById("check");
var checkbutton = document.getElementById("link3");
allowCheckbox.addEventListener("change", function(event) {
if (event.target.checked) {
checkbutton.disabled = false;
} else {
checkbutton.disabled = true;
}
}, false);
})
document.addEventListener("turbo:render", function() {
var allowCheckbox = document.getElementById("check");
var checkbutton = document.getElementById("link3");
allowCheckbox.addEventListener("change", function(event) {
if (event.target.checked) {
checkbutton.disabled = false;
} else {
checkbutton.disabled = true;
}
}, false);
})
実際に、バリデーションが実行された後でも、jsは機能しました。
おわりに
今回は、バリデーションが実行された時に、どのようにその画面に遷移してるかがポイントでした。loadであれば、いつも通り、jsは機能していましたが、バリデーションでrenderにしていたので、もう一つjsのコードを追加する必要があったのですね。
これは、これから先も使いそうな予感(?)がするので、覚えておこうと思います。
なかなか、読みやすさというものに欠けるかもしれませんが、誰かの問題を解く鍵になれば嬉しいでです。
ありがとうございました。