質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

解決済

1回答

1407閲覧

ajaxで呼び出したRailsのコントローラから他アクションにリダイレクトできない

SoyaSano

総合スコア9

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

1クリップ

投稿2019/01/09 11:07

発生している問題・エラーメッセージ

ajaxでrailsのコントローラを呼び出し、ているのですが、redirect_toが動作せず、指定先のアクションに移行しません。
コンソール上でエラー文は出力されず、原因がわかりません。

前提・実現したいこと

ブラウザの現在地情報を元にマップ上に近くお店を表示するアプリケーションを作ろうとしています。
■処理の流れ

  1. top.html.erb上の「近くのご飯を探す」ボタンをクリックして、food_menu.js内のgetFoodInfo() を呼び出す
  2. successCallback()関数内でajaxで/food_menu/searchをPOSTで呼び出す
  3. food_menu_controller.rb内のsearchメソッドでAPIを叩いたあと、showにリダイレクトする

使用技術

■言語/FW
Ruby on Rails 5.2.1
Ruby 2.5.3

■使用API
Geolocation API
Hotpepper API

該当のソースコード

food_menu/top.html.erb

<div class="container"> <div class="row"> <div class="col-md-8 food-search-form"> <h3>近くのワンコイン飯を探しましょう!</h3> <div> <input type="button" name="search-food" value="近くのご飯を探す" onClick="getFoodInfo()"> </div> </div> <div id="error_message"></div> </div> </div>

food_menu.js

javascript

1//***** ユーザーの現在の位置情報を取得 ***** 2function successCallback(position) { 3 4 var lat = position.coords.latitude; 5 var long = position.coords.longitude; 6 7 $.ajax({ 8 url: '/food_menu/search', 9 type: 'POST', 10 dataType: 'js', 11 // 非同期ならtrue、同期ならfalse。 12 async: true, 13 data: { 14 latitude: lat, 15 longitude: long 16 }, 17 }); 18} 19 20//***** 位置情報が取得できない場合 ****** 21function errorCallback(error) { 22 var err_msg = ""; 23 24 switch(error.code) 25 { 26 case 1: 27 err_msg = "位置情報の利用が許可されていません"; 28 break; 29 case 2: 30 err_msg = "デバイスの位置が判定できません"; 31 break; 32 case 3: 33 err_msg = "タイムアウトしました"; 34 break; 35 } 36 document.getElementById("error_message").innerHTML = err_msg; 37} 38 39function getFoodInfo(){ 40 navigator.geolocation.getCurrentPosition(successCallback, errorCallback); 41}

food_menu_controller.rb

Ruby

1class FoodMenuController < ApplicationController 2 3 def top 4 end 5 6 def search 7 response = get_menues_from_api(params[:latitude], params[:longitude]) 8 result = "" 9 message = "" 10 11 begin 12 # responseの値に応じて処理を分ける 13 case response 14 # 成功した場合 15 when Net::HTTPSuccess 16 # responseのbody要素をJSON形式で解釈し、hashに変換 17 result = JSON.parse(response.body) 18 # 別のURLに飛ばされた場合 19 when Net::HTTPRedirection 20 message = "Redirection: code=#{response.code} message=#{response.message}" 21 # その他エラー 22 else 23 message = "HTTP ERROR: code=#{response.code} message=#{response.message}" 24 end 25 26 rescue IOError => e 27 message = "e.message" 28 rescue TimeoutError => e 29 message = "e.message" 30 rescue JSON::ParserError => e 31 message = "e.message" 32 rescue => e 33 message = "e.message" 34 ensure 35 p "Reached ensure block!" 36 redirect_to food_menu_show_path 37 end 38 end 39 40 def show 41 p "show!" 42 @food_map = params[:food_map] 43 @message = params[:message] 44 end 45 46 def index 47 end 48 49 private 50 51 def get_menues_from_api(lat, lng) 52 # 現在地からお店情報を取得するクエリを作成 53 query = "http://webservice.recruit.co.jp/hotpepper/gourmet/v1/?key=<apiのkey>&format=json" 54 query += "&lat=" + lat 55 query += "&lng=" + lng 56 57 uri = URI.parse(query) 58 #クエリ実行 59 response = Net::HTTP.start(uri.host, uri.port) do |http| 60 # 接続時に待つ最大秒数を設定 61 http.open_timeout = 5 62 # 読み込み一回でブロックして良い最大秒数を設定 63 http.read_timeout = 10 64 65 http.get(uri.request_uri) 66 end 67 68 response 69 end 70 71end

food_menu/show.html.erb

<!DOCTYPE html> <html lang="ja"> <head> <meta charset=utf-8> <title>Geolocation API サンプル</title> </head> <body> <p>あなたの近くの検索結果</p> <div id="food_map"> <%= @food_map["shop"][0] %> <%= @message %> </div> <div id="error_message"></div> </body> </html>

routes.rb

Rails.application.routes.draw do root to: 'food_menu#top' get 'food_menu/index' post 'food_menu/search', to: 'food_menu#search' get 'food_menu/show' # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html end

rails routes 実行結果

$ rails routes Prefix Verb URI Pattern Controller#Action root GET / food_menu#top food_menu_index GET /food_menu/index(.:format) food_menu#index food_menu_search POST /food_menu/search(.:format) food_menu#search food_menu_show GET /food_menu/show(.:format) food_menu#show

試したこと

binding.pryを使用し、food_menu_controller.rbのsearchメソッド内でbegin~ensure の内容は問題なく動いていることを確認しました。
・redirect_toの直前で "Reached ensure block!"という文字列を出力させ、直前までは動いていることを確認しました。
・redirect_toではなく、render 'show' に変更しましたが挙動は変わりませんでした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Rubyのことは分かりませんが、Ajaxがそもそもバックグラウンドでサーバー側の処理を行っているということはご理解されてますでしょうか?
画面を伴うわけではないのでクライアント側(ブラウザ)からAjaxでサーバー側の処理を行ったら自動的にクライアント側に返ってきます。
結果はサーバー側で出力された文字列をdoneなどで受け取ることになります。

リダイレクトさせたいのであればAjaxを使うのではなくふつうにform送信するか、Ajax通信の成功とその結果をもってJavaScript側でリダイレクトを書くことになります。

投稿2019/01/09 11:48

m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SoyaSano

2019/01/09 12:18

ご回答ありがとうございます! そもそもajaxの処理の流れをあまり理解せずに使用していました。 今回書いた処理ではajaxは非同期通信で実行していたので、Ruby側で行っている内容にかかわらず、クライアント側で処理が完結してしまったという感じでしょうか?
m.ts10806

2019/01/09 12:25

非同期でも同期でもAjaxが「バックグラウンドで実行している」というのは同じです。 Ajaxの処理の流れは クライアント側からリクエストを画面遷移を伴うことなくサーバー側に送る →サーバー側はリクエストを受け取って処理を行いレスポンスを出力 →クライアント側で出力された内容を受けとる です。 この「リクエスト中にクライアント側で操作ができるかどうか」がAjaxの「async」というオプションです(デフォルトはtrue:非同期)。ここをfalse:同期にしたところで「通信中にクライアント側の操作が不可能(やってみると分かりますが通信が終わるまで画面がフリーズしたような状態になります)」というだけであり、やっていることは上記流れと同じです。 [Ajax 処理の流れ] などキーワードで検索するともっと詳しく書いてある記事やサンプルコードがある記事もあるので参考にしてください。
SoyaSano

2019/01/09 14:04

ありがとうございます! 処理の流れを調べた上で、もう一度書いています!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問