Help us understand the problem. What is going on with this article?

Rails 5.x標準で Ajax+(jQuery+Partial) でHTML部分更新する世界一シンプルなサンプル

More than 1 year has passed since last update.

2019/12/03追記

Rails 6.0.x 版を書きました ↓
Rails 6.0.x標準で Ajax+(jQuery+Partial) でHTML部分更新する世界一シンプルなサンプル

TL;DR (長い3行で)

Ajaxの勉強をするにあたり,Rails上でAjaxするためのサンプルを探していたのですが,Rails 5.xがもともとテンプレとして持っている.html.erb.coffeeではなく,.html.haml.js.erbを使ったものもあり,ヨコ道知識を調べながらになってしまったので,できる限りrails newした状態からの差分が少ない,世界一シンプルなサンプルコードを目指してまとめてみました.

ざっくりシーケンス

だいたい ↓ のようなシーケンスを実現します.
Client-Server間でSession張って双方向通信とかそういうところはRails Frameworkが全部やってくれているようで,Rails Developerが考える処理はとても少ないですね.

Front End : UserがInputしたTextをAjaxでBack End側にPost
↓
Back End : PostされたTextとPartialを使って部分的に差し替えるHTMLをRendering
↓
Front End : .coffee (Java Script)でAjaxのCallbackを受け取る
↓
Front End : jQueryでHTMLの部分差し替え

Project作成

いつもの ↓ のコマンドでProjectを作成+Project Dirに移動します.

$ rails new ajax_test
$ cd ajax_test

この時点で
$ rails s
でサーバ起動すると,
http://localhost:3000/
にアクセスしてDefaultのRootページが表示されます.

Static Page作成

Ajax実装のベースになるStatic Pageを実装します.

Controller

$ rails g controller AjaxTest
でControllerのテンプレを作成後,

app/controlles/rajax_test_controller.rb
class AjaxTestController < ApplicationController
  def top
    # NOP.
  end
end

Topページ用のActionを追加します.

Route Config

Controller+Actionを実装したので,Route ConfigにRoutingを追加します.

config/routes.rb
root  to: 'ajax_test#top'
post  'ajax_test/update', to: 'ajax_test#update', as: 'ajax_test_update'

Topページ表示用のRoute(root)とAjaxのRequest Post用のRouteの2本を追加しています.

View

ControllerとRouteができたので,残りはViewです.

app/views/ajax_test/top.html.erb
<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <div id="request_ajax_update" >
      <%= form_tag(ajax_test_update_path, method: :post, remote: true) { %>
        <%= text_field :data, :text %>
        <%= submit_tag 'Post AJAX' %>
      <% } %>
    </div>

    <hr>
    <div id="updated_by_ajax" >
      DEFAULT
    </div>
    <hr>
  </body>
</html>

大きく2つのブロックだけです.

<div id="request_ajax_update" >
Ajax RequestをPostするFormを持つブロック.
Userが入力したTextをparams[:data][:text]に詰めて,ajax_test/updateにPostします.

<div id="updated_by_ajax" >
Ajax Callbackを受けてHTMLの部分更新をするブロック.

この時点で,http://localhost:3000/にアクセスすると,↓ のようなページが表示されるはずです.

top_default.png

ただし,Ajaxの実装がまだ無いので,Post AJAXボタンをClickしても ↓ のようなエラーになります.(ControllerにActionの実装がない)

Started POST "/ajax_test/update"
AbstractController::ActionNotFound (The action 'update' could not be found for AjaxTestController):

Ajax実装

Ajax本体シーケンスの実装です.
さっき作ったStatic PageにAjax用の実装を追加していきます.

Controller

Ajax RequestのPostを受けるupdateのActionをControllerに追加します.

app/controllers/ajax_test_controller.rb
class AjaxTestController < ApplicationController
  def top
    # NOP.
  end

  def update
    post_text = params[:data][:text]
    results = { :message => post_text }
    render partial: 'ajax_partial', locals: { :results => results }
  end
end

Partial

Update Actionの中でRenderingしているPartialは ↓ のようなシンプルなものです.

app/views/ajax_test/_ajax_partial.html.erb
Callback Msg = <%= results[:message] %>

このPartialで<div id="updated_by_ajax" >の中身を差し替えます.

Coffee Script (Java Script)

Back EndからのAjax Callbackを受信する部分です.

app/assets/javascripts/ajax_test.coffee
$ ->
  $('#request_ajax_update')
    .on 'ajax:complete', (event) ->
      response = event.detail[0].response
      $('#updated_by_ajax').html(response)

Ajaxのcomplete callbackで渡されるeventはXMLHttpRequestの型の配列で,
event.detail[0].response
にBack End側でRenderingして返した部分HTMLが格納されています.
この部分HTMLをjQueryを使って差し替えます.

ただし,このままでTopページからPost AJAXをClickしても何も起こらない.
ChromeのDeveloper ToolでConsole Logをみると,

Uncaught ReferenceError: $ is not defined

というLogが出ている.
$が定義されていない = JQueryが使えていない,らしい.

jQueryを使えるようにする

Rails 5.xからjQueryが標準でサポートされなくなったとかあるらしく,自分で設定する必要があるらしい.

app/assets/javascripts/application.js
//= require jquery
//= require rails-ujs
//= require turbolinks
//= require_tree .

のようにapplication.js//= require jqueryを追加.
このままだとcouldn't findでerrorになるので,

Gemfile
gem 'jquery-rails'

を追加してbundle installしてから再度rails sすると,期待通りの動作をするようになるはず.

top_ajax.png

まとめ

素のRails 5.xの状態から最小CodeでAjaxを動作させるところまでのサンプルです.
ぼくみたいな街の組み込み屋はWeb Techに疎いので,本線一直線なシンプルなサンプルがあると助かります.

---///

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away