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

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

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

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

4797閲覧

RailsのControllerとJavaScriptのやり取りが上手くいかない

mizunana

総合スコア14

Ruby on Rails

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2018/07/26 09:37

編集2018/07/30 06:04

RailsのControllerで取得したデータベースをJavaScriptに渡してあげて、ページ遷移せずにページの切り替えをしようとしています。
Ajaxを使って、RailsのControllerを動かし、その際パラメータとして日付データを渡しています。初回のアクセス時は今日の日付で渡すようにControllerで分岐をさせています。
その日付データを使ってSQLを作成し、データベースを取得した後に、ControllerからJavaScriptに結果を渡しています。
そのときに使っているのは、Railsにある「gon」というgemです。gon.dataで受け渡しをしています。
受け取ったJavaScript側はAjaxのControllerでの動作が正常だった場合、ページ内の値をデータベースの結果にしようとしています。

しかし、ページが切り替わりません。
ログを見る限り、下記は成功しているようです。

・Controllerから指定の日付でSQLを投げる所(Railsのログより成功していることの確認
・初回で来た際には今日の日付でSQLを投げて、その結果を表示させる

出来ていないのが下記の通りです。

・初回アクセス後に今日の日付になっている値を変更し、JavaScriptを動かし(onChangeで)その結果を現在のページに反映させる

「gon」の内容がもしかしたら、上手く渡せていないのかなと思い調べている最中です。
ご教授頂ければ幸いです。

【追記1】
現状のコードはこうなっています

Ruby

1<div id="<%= program.id %>_title">タイトル</div>

今はこのコードなのですが、よく考えたら、HTML内をRubyで定義しちゃっているので破棄はしようと思っています。
JavaScriptが下記の通りです。

JavaScript

1 $.ajax({ 2 url: "/top", 3 type: "GET", 4 data: { days: days 5 }, 6 dataType: "html", 7 success: function(data) { 8 for (i in gon.program){ 9 document.getElementById(gon.program[i].id + "_title").innerHTML = gon.program[i].p_title 10 document.getElementById(gon.program[i].id + "_about").innerHTML = gon.program[i].about 11 } 12 }, 13 error: function(data) { 14 15 console.log("errror"); 16 17 } 18 });

Controller側が下記の通りです。

Ruby

1 if params[:days] == nil 2 @d1 = Date.today; p @d1 3 else 4 @d1 = params[:days] 5 end 6 @program = Program.where(day: @d1).order("start_time ASC") 7 gon.program = @program

【追記2】
試しに、下記のコードを作ってみました。

Ruby

1 function test(){ 2 console.log('テスト') 3 } 4 5 function test2(){ 6 gon.watch('program', interval:1000 ,test) 7 }

徐々に理解してきたのですが、test2を動かすとtestが動くと。
ただ、この状態ですと「Uncaught SyntaxError: missing ) after argument list」が発生し、うまく動きません。
intervalを削除して、('program', test)にすると、コンソールログに「テスト」が表示されます。

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

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

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

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

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

guest

回答1

0

ベストアンサー

多分みられてると思いますが、ドキュメントです
https://github.com/gazay/gon/wiki/Usage-gon-watch

・初回アクセス後に今日の日付になっている値を変更し、JavaScriptを動かし(onChangeで)その結果を現在のページに反映させる

質問ですが、表示したい日付を返すRailsのAPIは実装されていますか?
実装されているのであればそのControllerの中で

ruby

1gon.watch.渡したい値の変数名 = 渡したい値

を行い、JavaScriptでは

renewDate = (date) -> $('#latest_access_date').text(date) gon.watch(渡したい値の変数名, options, renewDate)

※optionsなどはドキュメントを見てください

のようにすれば動くんじゃないでしょうか?
なお、この実装だとページが表示されている間ずっとRailsにリクエストを投げ続けるため工夫が必要です。

投稿2018/07/27 01:57

satoshih

総合スコア797

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

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

mizunana

2018/07/27 08:37

なるほど、watchを使えば良いのですね。 少し試してみたのですが、どうにも使い方が分からなく……。 Controllerから日付を送ることは出来るのですが、これはAjax通信下で……ということでしょうか? コードを質問に追加しておきます。
satoshih

2018/07/27 12:34

gon.watch(渡したい値の変数名, options, renewDate) はoptionのインターバルで指定した値でRailsへGETリクエストを送って値を取得するものだと思いますので、 GETで日付が取得できるAPIを作成しこの関数でそのAPIを指定すれば動かないでしょうか?
mizunana

2018/07/30 04:54

度々すみません……watch関数に入っている最後のrenewDateというのが、毎回動くという認識であっていますでしょうか? あと、optionのインターバルを設定すると、Chromeのほうでエラーを吐いてしまいます……。 GETで日付を取得出来るAPIというのは、JavaScript上ででしょうか? また、この実装ですと「日付をユーザーに指定させて、その日付をControllerに投げる」仕組みなので、日付はJavaScript側で持っています。 すみません、まだ深く理解出来ていなくて変な質問かもしれませんが、お答え願えればと思います。
satoshih

2018/07/30 05:56

> 最後のrenewDateというのが、毎回動くという認識であっていますでしょうか? そうですそうです。 > Chromeのほうでエラーを吐いてしまいます……。 どんなエラーでしょうか? > GETで日付を取得出来るAPIというのは、JavaScript上ででしょうか? Rails側のWebAPIことです > この実装ですと「日付をユーザーに指定させて、その日付をControllerに投げる」仕組みなので、日付はJavaScript側で持っています。 あまりいい実装ではないですが、上記の `renewDate` 関数の引数に日付を渡すと$('#latest_access_date')のテキストを書き換えてくれるので、 Railsに更新をリクエストするのと同時にこの関数を呼び出すのが簡単かもしれないです
mizunana

2018/07/30 06:08

丁寧な回答本当にありがとうございます。凄く助かります。 質問にエラー文などを追記をしてみました。 もう一つ質問がありまして、watchの最初にある「渡したい値の変数名」は、ruby側で渡した変数名でしょうか? 「gon.watch.test = 'hoge'」 例えば、上記ですと gon.watch(test, interval: 1000, renewDate) このように記述するのが正しいですか?そうだと思い記載してみたのですが、やはりエラーが出てしまいました。エラーは下記の通りです。 「Uncaught ReferenceError: program is not defined」 なので、上手く受け取れていないのかなと思いました。 本当、丁寧にありがとうございます……またお答え願えればと思います。
satoshih

2018/07/30 06:15

gon.watch(test, interval: 1000, renewDate)ではなく gon.watch("test", interval: 1000, renewDate)かと思います 変数名は文字列で指定するようですね
mizunana

2018/07/30 06:19

ダブルクオーテーションで囲ってみたのですが、やはり 「Uncaught SyntaxError: missing ) after argument list」が出てしまいますね…… optionの設定方法が誤っているのか、色々試して居るのですが。
satoshih

2018/07/30 06:21

Controller側に gon.watch.program = Program.where(day: @d1).order("start_time ASC") と追記し、JavaScript側に gon.watch("program", interval: 1000, test) に変更でどうでしょうか?
satoshih

2018/07/30 06:22

> 「Uncaught SyntaxError: missing ) after argument list」が出てしまいますね これはRailsのログでしょうか?
mizunana

2018/07/30 06:24

> 「Uncaught SyntaxError: missing ) after argument list」が出てしまいますね >これはRailsのログでしょうか? こちらは、Chromeでのエラーログですね。
satoshih

2018/07/30 06:25

> missing ) after argument list これは引数のリストの後に)がないよというエラーなので、JavaScriptのシンタックスを見直して見てください
satoshih

2018/07/30 06:38

すいません、日付を更新したいだけでしたらもしかしたらRails側は gon.watch.program = @d1 か gon.watch.program = @d1,to_s かもしれないです
mizunana

2018/07/30 06:40

シンタックス見直し中ですが、見当たらず……シンプルにscriptの中にだけ入れてみましたが、intervalが入っているとエラーがどうしても抜けませんね。 あと、更新したいのは日付ではなくページに表示されているDBのオブジェクトなので、Program.wher~のほうで間違いないと思います。
mizunana

2018/07/30 06:57

すみません、初歩的なのですが、こちらcoffeescriptですね……。 ずっとHTML上の<script>で記載していたのですが、これが原因がかもしれません。
satoshih

2018/07/30 09:20

> 更新したいのは日付ではなくページに表示されているDBのオブジェクトなので、Program.wher~のほうで間違いないと思います。 Railsのオブジェクトをそのまま渡せるのかはちょっとわからないですね、もしかしたらJsonかHashに直さないと行けないかも? intervalのエラーは不思議ですね。。。 { interval: 1000 } にしても同様でしょうか?
mizunana

2018/07/30 09:25

一応watchを使わずに、gonでやった時はDBオブジェクトを持ってくる+内容を表示することは出来たので、出来ると思いました。 >{ interval: 1000 } この表記でエラー文消えました!ありがとうございます!! ……ここから実装なのですが gon.watch('program',{ interval: 1000 }, test() ); ここのprogramのオブジェクトは test関数内で使うには、どうすれば良いのでしょうか……?
satoshih

2018/07/30 09:33

> この表記でエラー文消えました!ありがとうございます!! よかったです。 > gon.watch('program',{ interval: 1000 }, test() ); これだとtestが直接呼ばれてしまうのでtestの ( ) はつけてはダメだと思いますよ。 watch関数には関数を引数で渡しますので > ここのprogramのオブジェクトは > test関数内で使うには、どうすれば良いのでしょうか……? オブジェクトの中身はJavaScriot(CoffeeScript)上ではどのような状態になっていますか?
mizunana

2018/07/30 09:41

>watch関数には関数を引数で渡しますので ということは、最終的に3つ目の引数には変数が入る(またはオブジェクト)という認識であっていますか? ()は外します。 >オブジェクトの中身はJavaScriot(CoffeeScript)上ではどのような状態になっていますか? オブジェクトは、DBを単純に持ってきたオブジェクトなので、レコード1つ1つを配列に詰め込んで、配列に入っているものを順番に出すというシンプルな構成です。
mizunana

2018/07/30 10:28

見てみたら、なんとかリクエストを何度も送るという所までは行きました(Ruby側のログで確認) あとはオブジェクトの取り方です……。すみません、本当長い時間お付き合い頂いて。ありがとうございます。
satoshih

2018/07/30 10:36

> ということは、最終的に3つ目の引数には変数が入る(またはオブジェクト)という認識であっていますか? いえ、3つ目の引数には関数が入ります。 その関数に対して、Railsでセットした値が引数として渡されます。 > オブジェクトは、DBを単純に持ってきたオブジェクトなので、レコード1つ1つを配列に詰め込んで、配列に入っているものを順番に出すというシンプルな構成です。 JavaScriot(CoffeeScript)で扱える状態でデータが取得できているのであれば、 あとはtest関数をHTMLのDOMを更新する関数にしてあげれば画面に反映できます
mizunana

2018/07/30 10:44

>あとはtest関数をHTMLのDOMを更新する関数にしてあげれば画面に反映できます なるほど……!理解しました、凄く分かりやすいです。これ本当にずっとリクエスト送り続けるんですね……制御が難しそうです。 取ってきたプログラムに応じて、HTMLの表示を変える仕組みをJavaScriptで組んでみようと思います。
mizunana

2018/07/31 04:50

度々ご相談させていただく形になるのですが、現状インターバルの通りに動く所までは確認致しました。 gon.watchの第一引数である'program'はControllerで代入した値が入っていて、その値を第三引数であるtestに渡された時に、testをtest(hoge)として定義していた場合、このhogeに入るという認識でしょうか?
satoshih

2018/07/31 06:38

> このhogeに入るという認識でしょうか? そのはずです
mizunana

2018/07/31 07:02

gon.watch('program',{ interval: 1000 }, getProgram ); (testからgetProgramにしました) こちらを動かした際には、処理順番としてはRailsのControllerを動かし、その結果をprogramに入れる。それをgetProgramに入れる形ですよね……? その、RailsのControllerを動かす時が、Ajax通信で動かしているという認識でしょうか? つまり、Postをしていることだと思うのですが、その時に投げるデータはoptionで設定する感じ……ですかね?
satoshih

2018/07/31 07:27

> Ajax通信で動かしているという認識でしょうか? そうですねAjaxです。 > Postをしていることだと思うのですが、その時に投げるデータはoptionで設定する感じ……ですかね? おそらくoptionsの method で指定しなければPOSTではなくGETだと思いますが、どんなリクエストが送られるかはRailsのログで確認できますよ optionsにはurlくらいしか指定できないので、仮に何か送る必要があるのでしたらクエリパラメータで送る必要があるとおもいます
mizunana

2018/07/31 10:11

>クエリパラメータで送る必要があるとおもいます こちらで試したら出来ました! DB取得が出来て、コンソールで配列指定で持ってくる所まで行けました。 ここまでこれたのも、satoshihさんのおかげです……!本当にありがとうございます! あとは、HTML側で出力する所と、インターバルの所を解決しようと思います。 一旦は解決にさせて頂きます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問