--- title: Rails 5.x標準で Ajax+(jQuery+Partial) でHTML部分更新する世界一シンプルなサンプル tags: Ruby Rails Ajax jQuery author: fezrestia slide: false --- # 2019/12/03追記 Rails 6.0.x 版を書きました ↓ [Rails 6.0.x標準で Ajax+(jQuery+Partial) でHTML部分更新する世界一シンプルなサンプル](https://qiita.com/fezrestia/items/9bf4e925314d7e6ec752) # 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のテンプレを作成後, ```ruby:app/controlles/rajax_test_controller.rb class AjaxTestController < ApplicationController def top # NOP. end end ``` Topページ用のActionを追加します. ## Route Config Controller+Actionを実装したので,Route ConfigにRoutingを追加します. ```ruby: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です. ```erb:app/views/ajax_test/top.html.erb
<%= form_tag(ajax_test_update_path, method: :post, remote: true) { %> <%= text_field :data, :text %> <%= submit_tag 'Post AJAX' %> <% } %>

DEFAULT

``` 大きく2つのブロックだけです. `
` Ajax RequestをPostするFormを持つブロック. Userが入力したTextを`params[:data][:text]`に詰めて,`ajax_test/update`にPostします. `
` Ajax Callbackを受けてHTMLの部分更新をするブロック. この時点で,`http://localhost:3000/`にアクセスすると,↓ のようなページが表示されるはずです. ![top_default.png](https://qiita-image-store.s3.amazonaws.com/0/129035/0446fd80-045e-54d1-dc46-6865a2413f2b.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に追加します. ```ruby: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は ↓ のようなシンプルなものです. ```ruby:app/views/ajax_test/_ajax_partial.html.erb Callback Msg = <%= results[:message] %> ``` このPartialで`
`の中身を差し替えます. ## Coffee Script (Java Script) Back EndからのAjax Callbackを受信する部分です. ```coffee: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が標準でサポートされなくなったとかあるらしく,自分で設定する必要があるらしい. ```javascript:app/assets/javascripts/application.js //= require jquery //= require rails-ujs //= require turbolinks //= require_tree . ``` のように`application.js`に`//= require jquery`を追加. このままだとcouldn't findでerrorになるので, ```ruby:Gemfile gem 'jquery-rails' ``` を追加して`bundle install`してから再度`rails s`すると,期待通りの動作をするようになるはず. ![top_ajax.png](https://qiita-image-store.s3.amazonaws.com/0/129035/e8238c96-b96e-9771-9cb1-e394454724eb.png) # まとめ 素のRails 5.xの状態から最小CodeでAjaxを動作させるところまでのサンプルです. ぼくみたいな街の組み込み屋はWeb Techに疎いので,本線一直線なシンプルなサンプルがあると助かります. ---///