

私は、今非同期通信で会話機能を導入しようと考えています。ページ移動なしで、データを表示することができるのですが、ページ移動・リロードなしで、表示することができない状態にあります。もしわかる方がいらしたら、方法を教えて頂きたいです。

[code]

    if Entry.where(:user_id => current_user.id, :room_id => params[:message][:room_id]).present?
        @message = Message.new(params.require(:message).permit(:user_id, :content, :room_id).merge(:user_id => current_user.id))
        if @message.save
            respond_to do |format|
                format.html { redirect_to :action => "show", :controller=>"rooms", :id => @message.room_id }
                format.json 
            end
        end
    else
        redirect_back(fallback_location: root_path)
    end
    
[/code]

[code]

    <% if @messages.present? %>
        <% @messages.each do |m| %>
        <strong><%= m.content %></strong>
        <small>by <strong><a href="/users/<%= m.user_id %>"><%= m.user.email %>さん</a></strong></small>
        <hr>
    <% end %>
    <% else %>
        <h3 class="text-center">メッセージはまだありません</h3>
    <% end %>
    
    <%= form_for @message,  id: "new_message" do |f| %>
        <%= f.text_field :content, class: "form__message", :placeholder => "メッセージを入力して下さい" , :size => 70 %>
        <%= f.hidden_field :room_id, class: "form__message", :value => @room.id %>
        <br>
        <%= f.submit "投稿する" , class: "form__message" %>
    <% end %>
    
[/code]

[code]

    <script type="text/javascript">
        $(document).ready(function() {
    
            $('#new_message').on('submit', function(e) {
                e.preventDefault();
                var formData = new FormData(this);
                var url = $(this).attr('action');
            })
        }
    
        $("#new_message").on('submit', function(e) {
            e.preventDefault();
            var formData = new FormData(this);
            var url = $(this).attr('action');
            $.ajax({
                url: url,
                type: "POST",
                data: formData,
                dataType: 'json',
                processData: false,
                contentType: false
            })
        }
    
        $(document).ready(function() {
            function buildHTML(message){
            var html = `<div class="message">
                            <div class="upper-message">
                                <div class="upper-message__user-name">
                                    ${ content }
                                </div>
                            </div>
                        </div>`;
            }
            return false;
    
            function scroll() {
                $('.messages').animate({scrollTop: $('.message')[0].scrollHeight});
            }
    
            $("#new_message").on('submit', function(e) {
    
                e.preventDefault();
                var formData = new FormData(this);
                var url = $(this).attr('action');
                $.ajax({
                    url: url,
                    type: "POST",
                    data: formData,
                    dataType: 'json',
                    processData: false,
                    contentType: false
                });
    
                .done(function(data){
                    var html = buildHTML(data);
                    $('.messages').append(html);
                    $('.form__message').val('');
                    $('.form__submit').prop('disabled', false);
                });
                scroll()
            });
        };
    </script>
    
[/code]

・jbuilder

[code]

    json.id @message.id
    json.content @message.content
    json.room_id @message.room_id
    json.user_id @message.user_id
    
[/code]


CC BY-SA 4.0
2020-04-21T07:18:26.930
65814
2020-04-22T03:57:00.563
2020-04-21T17:03:15.450
3060
30829
question
javascript ruby-on-rails ruby jquery
非同期通信で会話機能を導入しているのですが、ページをリロードしないで、データを表示することができません。


単純な文法間違い？`$.ajax()`の後ろに`.done()`をつなげる前に`;`が入ってるからじゃないですかね？？


CC BY-SA 4.0
2020-04-22T03:47:08.663
65842
2020-04-22T03:47:08.663
39761
65814
answer


問題を切り分けましょう。

【１、大前提として、jsやjQueryの基本的なミスがないか？】

・readyの外側で$(...).onバインドは一般的ではありません。  
処理順序を明確に理解してないのであれば、避けるべきでしょう。  
また、readyの書き方は、jQuery3.0以降であれば、$(handler)が推奨されています

・javascriptにミスがある様に見える  
buildHTML()ですが、message引数使ってないように見えます…？あとインデントは揃えましょう。

【２．Ajax処理周りの切り分け】

  1. RailsのView（つまり生成されたhtml自体）にミスがある可能性  
→ chromeでF12を押して、実際に生成されたhtml DOMが自分の想定通りか確認してください

  2. Ajaxで呼び出したURLに対するサーバ側が、うまくいっていない可能性  
→ 適当な関数でログをテキスト出力することは可能なはずです。  
想定したサーバサイドのコントローラーが呼ばれたか確認してください。

  3. Ajax通信が失敗している可能性  
→ 前提としてAjaxは、必ずdone, fail, alwaysをセットで書きましょう。  
詳細はajaxのリファレンスを参照してください。  
また、これらにalert()なりconsole.log()なりで、どれが実行されたかどうかを確認してください  
Ajax通信にはいくつかの制約があります  
・ページ自体とAjaxリクエストする先が同一生成元でない（クロスドメインである）場合、  
サーバ側がCORS対処しないと失敗する  
・GETリクエストならjsonpで回避することは可能だがjsonpの場合、  
エラーが発生したときにエラーの原因は読み取れない


CC BY-SA 4.0
2020-04-22T03:57:00.563
65843
2020-04-22T03:57:00.563
25396
65814
answer