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

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

ただいまの
回答率

90.34%

  • JavaScript

    17551questions

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

  • Ruby on Rails

    7693questions

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

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

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 219

cbl.Takuya

score 4

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】
現状のコードはこうなっています

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

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

        $.ajax({
                url: "/top",
                type: "GET",
                data: { days: days
                                },
                dataType: "html",
                success: function(data) {
                    for (i in gon.program){
                        document.getElementById(gon.program[i].id + "_title").innerHTML = gon.program[i].p_title
                        document.getElementById(gon.program[i].id + "_about").innerHTML = gon.program[i].about
                    }
                },
                error: function(data) {

                    console.log("errror");

                }
            });

Controller側が下記の通りです。

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

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

    function test(){
        console.log('テスト')
    }

    function test2(){
        gon.watch('program', interval:1000 ,test)
    }

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

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

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

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

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

を行い、JavaScriptでは

renewDate = (date) ->
  $('#latest_access_date').text(date)

gon.watch(渡したい値の変数名, options, renewDate)


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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/27 17:37

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

    コードを質問に追加しておきます。

    キャンセル

  • 2018/07/27 21:34

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

    キャンセル

  • 2018/07/30 13:54

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

    すみません、まだ深く理解出来ていなくて変な質問かもしれませんが、お答え願えればと思います。

    キャンセル

  • 2018/07/30 14:56

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

    キャンセル

  • 2018/07/30 15:08

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

    本当、丁寧にありがとうございます……またお答え願えればと思います。

    キャンセル

  • 2018/07/30 15:15

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

    キャンセル

  • 2018/07/30 15:19

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

    キャンセル

  • 2018/07/30 15:21

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

    キャンセル

  • 2018/07/30 15:22

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

    キャンセル

  • 2018/07/30 15:24

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

    キャンセル

  • 2018/07/30 15:25

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

    キャンセル

  • 2018/07/30 15:38

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

    gon.watch.program = @d1,to_s
    かもしれないです

    キャンセル

  • 2018/07/30 15:40

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

    キャンセル

  • 2018/07/30 15:57

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

    キャンセル

  • 2018/07/30 18:20

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

    キャンセル

  • 2018/07/30 18:25

    一応watchを使わずに、gonでやった時はDBオブジェクトを持ってくる+内容を表示することは出来たので、出来ると思いました。

    >{ interval: 1000 }
    この表記でエラー文消えました!ありがとうございます!!

    ……ここから実装なのですが
    gon.watch('program',{ interval: 1000 }, test() );

    ここのprogramのオブジェクトは
    test関数内で使うには、どうすれば良いのでしょうか……?

    キャンセル

  • 2018/07/30 18:33

    > この表記でエラー文消えました!ありがとうございます!!
    よかったです。

    > gon.watch('program',{ interval: 1000 }, test() );
    これだとtestが直接呼ばれてしまうのでtestの ( ) はつけてはダメだと思いますよ。
    watch関数には関数を引数で渡しますので

    > ここのprogramのオブジェクトは
    > test関数内で使うには、どうすれば良いのでしょうか……?
    オブジェクトの中身はJavaScriot(CoffeeScript)上ではどのような状態になっていますか?

    キャンセル

  • 2018/07/30 18:41

    >watch関数には関数を引数で渡しますので
    ということは、最終的に3つ目の引数には変数が入る(またはオブジェクト)という認識であっていますか?
    ()は外します。

    >オブジェクトの中身はJavaScriot(CoffeeScript)上ではどのような状態になっていますか?
    オブジェクトは、DBを単純に持ってきたオブジェクトなので、レコード1つ1つを配列に詰め込んで、配列に入っているものを順番に出すというシンプルな構成です。

    キャンセル

  • 2018/07/30 19:28

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

    キャンセル

  • 2018/07/30 19:36

    > ということは、最終的に3つ目の引数には変数が入る(またはオブジェクト)という認識であっていますか?
    いえ、3つ目の引数には関数が入ります。
    その関数に対して、Railsでセットした値が引数として渡されます。

    > オブジェクトは、DBを単純に持ってきたオブジェクトなので、レコード1つ1つを配列に詰め込んで、配列に入っているものを順番に出すというシンプルな構成です。
    JavaScriot(CoffeeScript)で扱える状態でデータが取得できているのであれば、
    あとはtest関数をHTMLのDOMを更新する関数にしてあげれば画面に反映できます

    キャンセル

  • 2018/07/30 19:44

    >あとはtest関数をHTMLのDOMを更新する関数にしてあげれば画面に反映できます
    なるほど……!理解しました、凄く分かりやすいです。これ本当にずっとリクエスト送り続けるんですね……制御が難しそうです。

    取ってきたプログラムに応じて、HTMLの表示を変える仕組みをJavaScriptで組んでみようと思います。

    キャンセル

  • 2018/07/31 13:50

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

    キャンセル

  • 2018/07/31 15:38

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

    キャンセル

  • 2018/07/31 16:02

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

    キャンセル

  • 2018/07/31 16:27

    > Ajax通信で動かしているという認識でしょうか?
    そうですねAjaxです。

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

    キャンセル

  • 2018/07/31 19:11

    >クエリパラメータで送る必要があるとおもいます
    こちらで試したら出来ました!
    DB取得が出来て、コンソールで配列指定で持ってくる所まで行けました。
    ここまでこれたのも、satoshihさんのおかげです……!本当にありがとうございます!

    あとは、HTML側で出力する所と、インターバルの所を解決しようと思います。
    一旦は解決にさせて頂きます!

    キャンセル

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

  • ただいまの回答率 90.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • JavaScript

    17551questions

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

  • Ruby on Rails

    7693questions

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