form_forをremote: trueでAjax実装

Railsのform_forでAjaxを実装する方法をまとめます。

以前も、いくつかRailsでAjaxを実装する方法をまとめていました。

今回は、form_forでAjaxを実装する方法です。いくつかハマりやすい落とし穴があるので、またハマらないように整理しておきます。

コントローラーの実装

コメントデータ(comment)を作成するフォームをAjaxで実装してみます。comments_controllerのcreateアクションです。

    def create
        @comment = Comment.new(comment_params)
        @comments = Comment.all
        if @comment.save
            @comment = Comment.new
        end
    end

フォームでsubmitした直後にAjaxで処理して、作成されたコメントを一覧で表示させるため、@commentsも定義しています。

フォームとコメント一覧

コメントを投稿するフォームと、コメント一覧を表示させるviewです。それぞれ部分テンプレートで実装しておき、あとでAjaxで扱いやすいようにしておきます。

投稿する
<div  id="comment_form">
    <%= render "comment_form", comment: @comment %>
</div>

コメント一覧
<div id='comment_area'>
    <%= render "comments", comments: @comments %>
</div>

フォームの部分テンプレート(_comment_form.html.erb)は下記のように実装します。Ajaxで処理するためにremote: trueを設定しておきます。これで、submit時にcreate.js.erbに処理が渡ります。

<%= form_for board, remote: true do |f| %>
    <div class='form-group mb-30'>
      <%= f.text_area :content %>
    </div>
      <%= f.submit :送信 %>
<% end %>

Ajax処理の実装

form_forにremote: trueを設定したことで、submit時にcreate.js.erbに処理が渡ります。

create.js.erbでは、投稿フォームとコメント一覧の箇所(部分テンプレートで記述した箇所)をJavascriptで動的に書き換えます。

$('#comment_area').html("<%= escape_javascript(render 'comments', comments: @comments) %>");
$('#comment_form').html("<%= escape_javascript(render 'comment_form',  comment: @comment) %>");

turbolinksに注意

以上で、form_forへのAjax処理が完成なのですが、うまく動かないときがあります。

僕がよくハマるのは、turbolinksが邪魔をしているケースです。

その場合は、Gemfileからturbolinksをコメントアウトします。

# gem 'turbolinks'

また、application.jsのturbolinksの呼び出しを削除します。

//= require turbolinks

を削除

更に、application.html.erbで、”data-turbolinks-track” => trueの部分をreloadに変更します。

<%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>

参考:

Ruby on Railsをこれから本格的に勉強したい人は「エンジニアになるための600時間のプログラミング学習に耐え抜くコツ」という記事がおすすめです。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする