LoginSignup
6
4

More than 5 years have passed since last update.

redirect_toでaction指定して、かつnoticeも設定しようとしたら、引数にハッシュを渡す云々で詰まった

Last updated at Posted at 2019-04-07

ケース

  • よくある作成処理で、画面遷移後にメッセージを表示したい。

結論

  • メソッド引数に複数のハッシュを渡す場合は、最後の引数以外は{}で囲う必要があります。
  • メソッドの第1引数にハッシュを渡す場合は、必ず()を付けてメソッドを呼び出す必要があります。
games_controller.rb
  def create
    @game = Game.new(game_params)
    if @game.save
      redirect_to({action: :index}, notice: '試合情報の作成に成功しました。')
    else
      render :new
    end
  end

※redirect_toと()の間にはスペースは入れられません。

失敗例

games_controller.rb
  def create
    @game = Game.new(game_params)
    if @game.save
      redirect_to action: :index, notice: '試合情報の作成に成功しました。'
    else
      render :new
    end
  end

実際に画面操作してみると、遷移後の画面にメッセージが表示されず(noticeを受けるように記述しているのに)、しかもURLが以下のようになっていました。

http://localhost:3000/games?notice=試合情報の作成に成功しました。

原因

ググりながら解決方法を見つけ、問題なく動くようになったのですが、原因はRubyの文法にありました。
プロを目指す人のためのRuby入門によると、メソッド引数にハッシュを渡す時のルールについて記載されていました。

Rubyでは「最後の引数がハッシュであればハッシュリテラルの{}を省略できる」というルールがあります。

失敗例のコードでは、{}を書いていなかったため、action: :index, notice: '試合情報の作成に成功しました。' の部分でひとつのハッシュと見なされてしまいます。
今回、redirect_toには「アクション」と「notice」のふたつのハッシュを渡す必要があるため、そこで上手くいっていなかったということです。

さらに

解決はしたのですが、そこで私は
「じゃあこう書いたらどうなる?メソッド呼び出しの()って省略できるんじゃなかったっけ?」
と、以下のコードを書きました。

games_controller.rb
  def create
    @game = Game.new(game_params)
    if @game.save
      redirect_to {action: :index}, notice: '試合情報の作成に成功しました。'
    else
      render :new
    end
  end

すると、画面操作する前にRubyMineに怒られました(Eclipseでいうコンパイルエラーみたいな感じで赤くなる)。
そのまま画面操作するとエラーになるようです。

プロを目指す人のためのRuby入門を読み進めると、次のページに同じケースについて書いてありました(著者の方に先を読まれているw)。

おや、エラーが発生してしまいました。(少し中略)実はこれは、ハッシュリテラルの{}がブロックの{}だとRubyに解釈されたためです。
(中略)
というわけで、このようにメソッドの第1引数にハッシュを渡そうとする場合は必ず()を付けてメソッドを呼び出す必要があります。

なるほどですね。。。
ということでやはり、上述のあの書き方でないとダメということですね。勉強になります!

参考

6
4
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4