Posted at

Railsのよしなに力が高すぎた話

More than 1 year has passed since last update.

Ruby 2.5

Rails5.1.x


次のようなソースがあるとします。

なにかを編集する画面です。モデルに@userとあるのできっとユーザーの情報でしょう。

なんと気分をCHANGE!ボタンがついている編集画面です。

楽しく作業ができそうですね。


<div id="content">
<%= form_with(model: @user) do |f| %>
<div>
<h1>なにかの編集画面</h1>
<div>
<%= f.submit "OK" %>
<%= button_tag "気分をCHANGE!", type: "button", onclick: "change_color()" %>
</div>
</div>
</div>
<p><span class="hissu-dayo">*</span>は必須入力項目です。</p>
<%= render :partial => "form", :locals => {:f => f } %>
<%= button_tag "すべてをRESET...", type: "button", onclick: "ex_death()" %>
<% end %>
</div>

<script>
function change_color(){
$("form input, form button").css('background-color',"skyblue");
}

function ex_death(){
(すべてのそんざい すべての次元を消し そして わたしも消える 処理);
}
</script>


ここで問題です。

気分をCHANGE!ボタンを押すとさわやかな空色に背景が変わるのは次のうちどれでしょう?

1, 「OK」ボタン

2, 「OK」ボタンと「気分をCHANGE!」ボタン

3, 「気分をCHANGE!」ボタンと「すべてをRESET...」ボタン

4, ALL-IN!


正解は。

2の「OK」ボタンと「気分をCHANGE!」ボタンでした。

聡明な読者の方には簡単すぎたかもしれませんね。

正解者に拍手!

…で終了というわけにもいかないので。


解説。

このソースでいうと、10行目のdivの閉じタグの前にformの閉じタグが挿入されます。

そう。お気づきになりましたでしょうか。なんとdivの閉じタグが一個多いのです。


<div id="content">
<%= form_with(model: @user) do |f| %>
<div>
<h1>なにかの編集画面</h1>
<div>
<%= f.submit "OK" %>
<%= button_tag "気分をCHANGE!", type: "button", onclick: "change_color()" %>
</div>
</div>
</div> <!-- この閉じタグがいらない! -->
<p><span class="hissu-dayo">*</span>は必須入力項目です。</p>
<%= render :partial => "form", :locals => {:f => f } %>
<%= button_tag "すべてをRESET...", type: "button", onclick: "ex_death()" %>
<% end %>
</div>

そして、formの閉じタグは<% end %>の記述箇所14行目ではなく、親のdivが閉じられる前に生成されることになります。

ので、みっつめのbuttonタグはformの下ではなくなり、セレクタ指定から外れることになるのでした。

この程度のソースなら問題解決まで早いですが、

実際のソースだと外部js呼び出していたり色んなfunction経由したり、そもそも原因がjsにあるのかのきりわけにも時間かかる。

つまり、マジで問題箇所が見つけられない。

半日かかりました。


結論

Railsはよしなに力が高い。

インデントはちゃんとしようね。してください。

(レガシーなコードを保守している場合もまわりを巻き込んで手を入れていきましょう!)


おまけ

現在携わっているプロジェクトでRailsのバージョンアップ中なのですが、Rails3.xでは起きていなかったので、

Railsもおにいさん(おねえさん?)になるに従ってよしなに力がどんどんあがっているということなんですね。