ネストがひどい
下のコードがスマートじゃない。(リダイレクトのパスとかは適当です)
# hoge_controller.rb def destroy if target = User.find_by(id: params["id"]) if current_user.unfollow(target) #フォローを外すみたいな動作 flash[:info] = I18n.t("hoge.destroy.success") else flash[:danger] = I18n.t("hoge.destroy.failure") end else flash[:danger] = I18n.t("hoge.destroy.user_not_found") end redirect_to(root_path) end
RuboCop先生曰く、制御構文で条件式のネストは避けましょう。
とのこと。ガード節
を使います。
ガード節
不正なデータを弾きたいときはガード節を使いましょう。 ガード節とは、できるだけ素早く関数から抜けられるようにと 関数の先頭に置かれている条件文のことです。
https://github.com/fortissimo1997/ruby-style-guide/blob/japanese/README.ja.md#no-nested-conditionals
return ~ unless
を使用して、予期しない条件の場合はこれ以降関係ないっすよ。ってしてあげることで、見た目的にも読みやすくなる気がします。if~else
が適しているものとして、条件分岐に相対性があるものとの噂もあったので、
# hoge_controller.rb def destroy target = User.find_by(id: params["id"]) return redirect_to(root_path, flash: { danger: I18n.t("hoge.destroy.user_not_found") }) unless target if current_user.unfollow(target) flash[:info] = I18n.t("hoge.destroy.success") else flash[:danger] = I18n.t("hoge.destroy.failure") end redirect_to(root_path) end
余談
上のコードのガード節でfind_by
行までまとめて1行で書く場合、
return redirect_to(root_path, flash: { danger: I18n.t("hoge.destroy.user_not_found") }) unless (target = User.find_by(id: params["id"]))
とかけますが、target
変数の出どころがわかりにくいので、2行にしてます。また、上記の場合、unless
の条件に()
つけないと、RuboCop先生に注意されますが、コード自体は走ります。(==
のタイポと思われる)