Help us understand the problem. What is going on with this article?

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

ケース

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

結論

  • メソッド引数に複数のハッシュを渡す場合は、最後の引数以外は{}で囲う必要があります。
  • メソッドの第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引数にハッシュを渡そうとする場合は必ず()を付けてメソッドを呼び出す必要があります。

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

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした