更新日:
【Rails】 Ajaxチュートリアル(Rails+jQuery)~処理の流れを理解しよう
少し難しいイメージがあるAjax実装ですが、この記事では「Rails + jQuery」を使った実装手順や処理の流れをチュートリアル形式で1つ1つ丁寧に解説します。是非Ajax実装をマスターしましょう!
「Rails + jQuery」でAjaxを実装すると、以下のアプリケーションのように画面遷移なしで検索したタイトルを表示する事も出来ます。
Ajaxとは、JavaScriptでサーバー側との通信を「非同期」で行い、通信結果によって「動的にページの一部だけ書き換える手法のこと」です。
そもそも「Ajaxって何だろう?」という方や「Ajaxの仕組み」について理解出来ていない方は、こちらの「Ajaxとは?初心者向けに仕組みを徹底解説!」を読んでからAjax実装に入りましょう。
Ajaxを実装する方法とは?
RailsでAjaxを実装する場合は、「form系のヘルパーメソッドにremote: trueを設定して実装する方法」と「jQueryの$.ajax()などで実装する方法」の2つの実装方法があります。
前者のremote: trueは簡単なAjaxの処理には対応できますが、複雑な処理になる場合は後者の$.ajax()などを使って実装します。
今回は、Ajaxを用いて以下のような「検索窓に文字を入力するたびにタイトルの候補を表示する(インクリメンタルサーチ)」といった少し複雑な処理を実装するので、後者の$.ajax()を使います。
Ajaxを用いてインクリメンタルサーチを実装する手順は、以下の通りです。
- 準備をしよう
- Viewを変更しよう
- データを送信しよう
- データをControllerで受け取ろう
- 検索処理を記述してレスポンスを返そう
- Controllerから受け取った内容をjsで反映させよう
Ajaxの実装に対して「なんだか難しそう」というイメージを持つ方が多いと思いますが、処理の流れを把握する事が出来れば、Ajax実装はそこまで難しいものではありません。
この記事では、アプリケーションを作成してAjaxの実装手順や処理の流れを1つ1つ詳しく解説します。手を動かす事で理解が一層深まるので、是非一緒に作成してみてください。
簡単なAjax処理をremote: trueで実装したい方は「remote: trueでAjax実装する方法」を参考にしてください。
1.準備をしよう
まずは、サンプルアプリケーションの用意や初期データの投入、そしてjQueryの導入やjsファイルの作成などAjaxの実装をする前に必要なものを準備します。
サンプルアプリケーションの用意
Ajax実装するサンプルアプリケーションは、メッセージのタイトルと内容を管理する事が出来るアプリケーションを作成します。
最初に、以下のrails newコマンドでsample_app
アプリケーションを作成します。
1
rails _5.2.1_ new sample_app -d mysql
次に、scaffold
でMessageモデルなど投稿メッセージを管理する為の雛形を作成します。メッセージのタイトルと内容が保存できるように、カラムはtitleとbodyを指定します。
1
2
3
cd sample_app # ディレクトリを移動
rails g scaffold Message title:string body:string # scaffoldを実行
# rails g scaffold モデル名 カラム名:型
そして、以下のコマンドでデータベースの作成とscaffoldの内容を元にして作成されたマイグレーションを実行します。
1
bundle exec rails db:create && bundle exec rails db:migrate
rails server
でサーバーを起動させてlocalhost:3000/messagesにアクセスすると、以下のようにメッセージの登録・一覧表示・編集の簡単な機能が作成されます。
上記のアプリケーションでは、以下のコードで背景色や入力フォームのサイズのスタイルを追加しています。
1
2
3
4
5
6
7
8
body {
background-color: #cad8ff;
}
input[type="text"] {
width: 300px;
height: 30px;
}
これは解説の為に追加したスタイルなので、特に追加する必要はありません。
初期データの投入
作成したばかりのアプリケーションは、データが空の状態なのでseedを使って初期データを投入します。
db/seeds.rb
に以下の内容をコピーして保存しましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 基本的な書き方
#モデル名.create!(
# カラム名: '値',
# カラム名: '値'
#)
# 以下のコードからコピーしてください。
Message.create!(
[
{
title: 'アウトプットの大切さ',
body: 'アウトプットするとは、インプットしたものを自分の価値観や考え方を通して、整理・発信したり自分に応用できる様に落とし込むこと。'
},
{
title: '「衣」で気持ちを服用する',
body: '自分の目で服用するという事が大事なので、外出用の洋服に着替えなくても、何か家の中や自分を元気にする薬を身近なところでこの状況下を乗り切りたいと感じた。'
},
{
title: '目的に関知しない',
body: '目的が規定されたツールを使う以上、僕たちが生み出せるものはその目的の範疇に収まってしまいがちであることに気づいた。ツールに操られていることを意識することで、少しでもそれに抗えるのではないかと思う。'
},
{
title: '「サービスの体験をよくする」事で考えること',
body: 'ユーザー体験は6段階に分けられて、これをUXピラミッドというらしいです。私は今まで漠然と何をすればいいかは把握してましたが、Lv1〜Lv6までに分けて低いところから満たしていくのは皆んなにわかりやすいと感じました。....'
},
{
title: '快の転移の仕組み',
body: 'ビールが飲めるようになったとき、コーヒーが美味しく感じるようになったとき、よく大人になったと言いますが、実はこういう仕組みだったのか...大人と全然関係ないじゃないか......'
},
]
)
そして、以下のコマンドをターミナルで実行します。
1
bundle exec rails db:seed
再び「localhost:3000/messages」にアクセスすると、以下の動画のようにdb/seeds.rb
に定義したデータが投入されて反映する事が出来ています。
このように、db/seeds.rb
にデータを定義してコマンド実行するだけで初期データを簡単に投入する事が出来ます。
jQueryの導入
次にjQueryを導入するために、以下のコードをGemfile
に追加してターミナルでbundle installを実行します。
1
gem "jquery-rails"
1
bundle install
bundle install
したら、インストールしたgemを読み込むためにサーバーを再起動させましょう。bundle execについては、「bundle execとは?」を参考にしてください。
1
bundle exec rails server
そしてJavaScriptでjQueryのライブラリを読み込んで有効化するために、以下のコードをapplication.js
に追加します。
1
//= require jquery
jsファイルの用意
最後にAjaxの処理を記述するmessages.js
ファイルを用意します。
scaffoldを実行すると、app/assets/javascripts/messages.coffee
が自動的に作成されますが、今回は使わないのでこちらのファイル名をmessages.jsにリネームします。
1
2
mv app/assets/javascripts/messages.coffee app/assets/javascripts/messages.js
# mv [変更前ファイル名] [変更後ファイル名]
コマンドを実行すると、上記のようにファイル名がmessages.jsに変更されます。このファイル内に記述されている全てのコード削除して以下のコードに書き換えておきます。
1
2
3
$(function () {
// ここに処理を記述する
});
それでは、jQueryが導入出来ているか確かめるために以下のコードを記述しましょう。
1
2
3
$(function () {
$("h1").css("color", "#0000FF");
});
「localhost:3000/messages」でページ再読み込み(⌘ + r
)して、h1の文字色が変更されたらjQueryの導入が成功しています。
反映されていない場合は、もう一度以下の項目を確かめてみて下さい。
- gemをinstallした後にサーバー再起動したか?
application.js
で追加したコード(//= require_tree .
)の位置はあっているか?messages.coffee
が存在していないか?(存在していた場合は削除する)- ページ再読み込み出来ているか?
これでAjax実装前の準備は終了しました。
次のセクションからいよいよAjax実装に入ります。この調子で1つ1つクリアしていきましょう!
2.Viewを変更しよう
今回は、用意したアプリケーションにAjaxを用いて「検索窓に文字を入力するたびにタイトルの候補を表示させる」というインクリメンタルサーチを実装します。
まずは、以下のようにscaffold
で用意したメッセージ一覧画面に検索窓を設置し、メッセージのタイトル一覧に変更します。
検索窓の設置
検索窓はフォームに文字が入力出来れば良いので、form_withなどのフォームヘルパーではなくtext_field_tag
を使って作成します。
まずは、index.html.erb
を以下のコードに書き換えます。
1
2
3
4
5
6
<h1>タイトル一覧</h1>
<div class="contents">
<%= text_field_tag :title,'', class: 'js-text_field', placeholder: 'タイトルを入力してください' %>
</div>
<%= link_to 'New Message', new_message_path %>
上記で検索窓を作成するために記述したtext_field_tag
の部分は、以下のようにコンパイルされます。
1
2
3
4
5
<!-- コンパイル前 -->
<%= text_field_tag :title,'', class: 'js-text_field', placeholder: 'タイトルを入力してください' %>
<!-- コンパイル後 -->
<input type="text" name="title" id="title" value="" class="js-text_field" placeholder="タイトルを入力してください">
text_field_tag
の第二引数には値を指定する必要があるので、コンパイル前のコードでは第二引数に''
を指定しています。そして、値が空なのでvalue=""
にコンパイルされます。
部分テンプレートの追加
そして、index.html.erb
に更に以下のコードを追加します。
1
2
3
4
5
6
7
8
9
10
11
12
<h1>タイトル一覧</h1>
<div class="contents">
<%= text_field_tag :title,'', class: 'js-text_field', placeholder: 'タイトルを入力してください' %>
<!-- 以下のコードを追加する-->
<ul class="js-messages">
<%= render @messages %><!-- 部分テンプレートを呼び出し-->
</ul>
</div>
<%= link_to 'New Message', new_message_path %>
上記で追加した<%= render @messages %>
は、部分テンプレート呼び出しの省略した書き方です。
これで呼び出されるファイルはapp/views/messages/_message.html.erb
ですが、ファイルがないので以下のコマンドで作成します。
1
touch app/views/messages/_message.html.erb
作成したファイル内には、以下のコードを記述します。
1
<li class="message"><%= link_to message.title, message %></li>
上記のmessageには、呼び出し側で渡している@messages(全てのメッセージの情報を格納)の中身が1つ1つ渡されます。中身が全て渡されるまでこの部分テンプレートが呼び出されるので、以下のように全てのメッセージのタイトルのリンクを表示されます。
ここまでのView変更の完成図は以下の通りです。
まだ機能していない検索窓の設置と部分テンプレートでタイトル一覧のリンクを表示する事が出来ました。
部分テンプレートの使い方について詳しくは、こちらの「部分テンプレートの使い方」を参考にしてください。
3.データを送信しよう
次は、検索窓に入力した値を取得して、そのデータをRails側にリクエストを送信するところまで実装します。
検索窓に入力された値を取得
まずは、検索窓に入力された値を取得していきましょう。
検索窓のinput要素には、以下のようにjs-text_filed
のクラスが付与されています。このクラスを使って値を取得する事が出来そうです。
以下のようにChromeデベロッパーツールのConsoleに、jQueryで.js-text_filed
を指定してval()
を使用する事で、検索窓の値を取得出来ることが分かります。
これによりタイトル一覧ページの読み込みが完了してから実行するmessages.js
ファイルの$(function(){}
内には、以下のように記述する事で検索窓の値を取得出来ます。
1
2
3
4
5
6
$(function () {
var textField = $('.js-text-field');
// $.trim()で値の前後の空白を削除
var title = $.trim(textField.val());
});
しかし、上記のコードだと「いつ」のタイミングで検索窓の値を取得するのか無い状態です。このタイミングの付け方ですが、例えば以下のようにon()
を使ってkeyupのイベント処理を結びつけたとします。
1
2
3
4
5
$(function () {
$('.js-text_field').on('keyup', function () {
console.log("キーボードを入力した時に発生");
})
});
このようにすると、キーボードを入力するたびにconsole.log("キーボードを入力した時に発生")
が実行されるのが、以下の動画からも分かりますね。
検索窓の値を取得するタイミングも「キーボードを入力するたび」にしたいので、$(function(){}
内を以下のように記述します。
1
2
3
4
5
6
7
8
9
$(function () {
$('.js-text_field').on('keyup', function () {
// キーボードを入力したタイミングで以下の処理を実行する
var textField = $('.js-text_field');
var title = $.trim(textField.val());
console.log(title); // 検索窓の値が取れているか確認
});
});
上記のコードで追加したconsole.log(title)
によって、以下のように検索窓で文字を入力しキーボードを入力する度に「検索窓の値を取得出来ているか」をConsoleで確認が取れます。
以下のコードで検索窓の値の取得は終わりですが、もう少しシンプルに記述する事が出来るのでリファクタリングします。
1
2
3
4
5
6
$(function () {
$('.js-text_field').on('keyup', function () {
var textField = $('.js-text_field');
var title = $.trim(textField.val());
});
});
上記のtextField
には$('.js-text_field')
が格納されていますが、$(this)を使う事が出来ます。$(this)
とは、以下の画像のようにイベントが発生した要素の情報の事です。
つまり、.js-text_field
のタグとタグの内部の情報を指しているので、緑枠で囲う箇所は$(this)
に変更する事が出来ます。そしてtextField
を使わなくても、以下のように直接$(this)
を記述する事でよりシンプルになります。
1
2
3
4
5
6
$(function () {
$('.js-text_field').on('keyup', function () {
var title = $.trim($(this).val());
console.log(title); // 検索窓の値が取れているか確認
});
});
リファクタリングは以上になりますが、コードが正常に動くかconsole.log(title)
で以下のように確認します。
問題なく動いていますね。リファクタリングした事でかなりシンプルなコードになりました。最後にconsole.log(title)
は、動作確認のコードなので消しておきましょう。
1
2
3
4
5
$(function () {
$('.js-text_field').on('keyup', function () {
var title = $.trim($(this).val());
});
});
thisについて詳細は「thisについて理解しよう(関数呼び出し編)」を参考にしてください。
$.ajax()でリクエストを送信
ajax通信までの準備はできたので、これから下記の動画の様に$.ajax()メソッドを使ってインクリメンタルサーチを実装していきます。
$.ajax()メソッドを使ってRails側にリクエストを送る流れは、下記になります。
- 検索窓から検索ワードを取得する。
- 取得した検索ワードを$.ajax()メソッドを使ってRails側にリクエスト
1は前章で実装したので、これから2の「$.ajax()メソッドを使ってRails側にリクエスト」を実装していきます。
まずは、リクエストの送信が出来るように$.ajax()
を使います。
1
2
3
$.ajax({
// リクエストの設定項目
)}
$.ajax()
で設定出来るリクエストの項目には、以下のようなものがあります。
設定項目 | 内容 | 例 |
---|---|---|
type | リクエストのタイプ | type: 'POST' 、type: 'GET' |
url | リクエストを送信するURL | url: '/messages/searches' |
data | サーバーに送信するデータ | data: { title: title } |
dataType | 期待するサーバーから返却される型 | dataType: 'json' |
今回は、検索窓から取得した値(title
)のデータを'/messages/searches'
にGETでリクエストを送信したいので、以下のように設定します。
1
2
3
4
5
6
7
8
9
10
11
12
13
$(function () {
$('.js-text_field').on('keyup', function () {
var title = $.trim($(this).val());
// 追加コード
$.ajax({
type: 'GET', // リクエストのタイプ
url: '/messages/searches', // リクエストを送信するURL
data: { title: title }, // サーバーに送信するデータ
dataType: 'json' // サーバーから返却される型
})
});
});
最後のdataType
には、サーバーから返される型にJSONを指定します。(詳細は後述します。)そして、サーバー側との通信を「非同期」で行います。
これでリクエスト送信の設定は完了しました。実際にリクエスト送信してデータを受け取れているかは、次のセクションのControllerを作成してから確認します。
4.データをControllerで受け取ろう
前のセクションで$.ajax()
を使ってリクエスト送信までの設定が終わりましたが、今度はリクエストされたデータをControllerで受け取れるように、ルーティングの設定と検索処理するコントローラを作成します。
検索処理をするコントローラを作成
$.ajax()
でリクエストされた検索窓のデータを受け取って処理をするコントローラは、以下のapp/controllers/messages/searches_controller.rb
に記述していきます。
このmessages
ディレクトリとsearches_controller.rb
ファイルはまだ作成していないので、以下のコマンドで作成します。
1
mkdir app/controllers/messages && touch app/controllers/messages/searches_controller.rb
上記で作成したsearches_controller.rb
には、以下のコードを記述します。
1
2
3
4
class Messages::SearchesController < ApplicationController
def index
end
end
Railsではファイル構造とクラス名を合わせる必要があるので、上記のようにクラス名にMessages::
を付ける事で、この「SearchesController
はmessages
ディレクトリ配下にあるController」だと認識されます。
ルーティングの設定
次にルーティングの設定を行います。ここまでで決まっていることは、以下の通りです。
$.ajax()
でリクエストを送信するURLは、/messages/searches
です。- 上記で送信されるデータを受け取るのは、
Messages::SearchesController
のindexアクション
です。
上記より、「/messages/searches」にリクエストが送信された場合は、Messages::SearchesController
のindexアクション
が動いて欲しいので、ルーティングの設定を以下のように記述します。
1
2
3
4
5
6
7
8
Rails.application.routes.draw do
# 以下のブロックを追加する
namespace :messages do
resources :searches, only: :index, defaults: { format: :json }
end
resources :messages # このコードより上に追加する(※補足説明へ)
end
上記の設定で生成されるルーティングは、以下の通りです。(ターミナルでrails routesを実行してます。)
このようにnamespace
で定義すると、URLだけではなくコントローラのファイル構成も指定したパス通り(/messages/searches)になります。
データを受け取れているか確認
これまでの$.ajax()
やルーティングなどの設定によって、以下の画像の様に検索窓に文字を入力した際にMessages::SearchesControllerのindexアクション
で検索窓の値を受け取る事ができているのか確認します。
ここまでに行った設定や流れの詳細は、以下の通りです。
- 検索窓に文字を入力
- キーボードを入力する度に検索窓の値を取得
- このデータを
$.ajax()
で/messages/searches
にリクエストを送信 - ルーティングで上記のURLがきたら
Messages::SearchesController
のindexアクション
が動くように設定
それでは、データを受け取れているか確認しましょう。
まずは、以下のコードのように「binding.pry」追加して、indexアクションが動いたら処理を止める様にします。(このgemは、pry-railsを参考にインストールしてください。)
1
2
3
4
5
class Messages::SearchesController < ApplicationController
def index
binding.pry # 追加する
end
end
キーボードを入力した時に検索窓の値が取得されて、その値を$.ajax()
の設定によって/messages/searches
に送信され、Messages::SearchesControllerのindexアクションが動くので、binding.pry
を記述した箇所で処理が止まるはずです。
以下の動画の様に検索窓に文字を入力すると、ターミナルでプログラムの実行が停止されてPryが起動します。
そして、paramsを実行すると送信されたパラメータが表示されて、検索窓の値を{"title" => "検索窓の値"}
として受け取れている事が分かります。このtitleというのは、以下の画像の様に$.ajax()
のdata
でtitleのキーに検索窓の値を設定したからです。
また、Pryにrequest.formatを実行すると、リクエストされる形式がjsonである事が分かります。これは、上記のdataTypeで'json'
を指定したからです。
ここまでの設定で無事検索窓に入力した値を受け取る事が出来たので、その値を含むタイトルがあるかという検索処理を実装します。
5.検索処理を記述してレスポンスを返そう
次にindexアクション
に検索処理を記述して、その結果をレスポンスします。ここでの1番の実装ポイントは、検索結果のオブジェクト(@messages)をそのまま返すのではなく、JSON形式のデータに変換してから返すという点です。
それでは、実装していきます。
検索窓の値は、先ほどのPryでparamsの中のtitleに格納されていた事が分かったのでparams[:title]
の記述で取得できますね。
これを踏まえてindexアクションには、以下の「検索処理のコード」と「検索結果のデータ(@messages)をレスポンスするコード」を記述します。
1
2
3
4
5
6
7
8
9
10
11
12
class Messages::SearchesController < ApplicationController
def index
# ↓検索処理のコード
@messages = Message.where('title LIKE(?)', "%#{params[:title]}%")
respond_to do |format|
format.html { redirect_to :root }
# ↓検索結果のデータをレスポンスするコード
format.json { render json: @messages }
end
end
end
上記の検索処理のコードですが、whereメソッドとLIKE句のあいまい検索を使ってtitleカラムにparams[:title]
の値を含む全てのレコードを取得します。
これは、実際にアプリケーションを動かしたほうが理解しやすいので、以下のようにbinding.pryを追加して確認します。
1
2
3
4
5
class Messages::SearchesController < ApplicationController
def index
@messages = Message.where('title LIKE(?)', "%#{params[:title]}%")
binding.pry # 追加
# 以下省略
検索窓には、以下の動画のように「の」を入力してPryを起動させます。
そして、@messages
を確認するとタイトルに「の」という値を含むレコードを全て取得しています。
また、以下の動画のように検索窓に「大切」と入力すると、@messagesには、メッセージのタイトルが「大切」という値を含むレコードが取得されます。
このように、@messages
は検索窓の値を含むタイトルのレコードが全て格納されます。
そして、以下のように「respond_toメソッド」を使ってリクエストの形式ごとに処理を切り分けます。(詳細は、「respond_toメソッドの使い方」を参考にしてください。)
1
2
3
4
5
6
7
8
9
class Messages::SearchesController < ApplicationController
def index
@messages = Message.where('title LIKE(?)', "%#{params[:title]}%")
respond_to do |format| # リクエスト形式によって処理を切り分ける
format.html { redirect_to :root } # html形式の場合
format.json { render json: @messages } # json形式の場合
end
end
end
json形式でリクエストが送信された場合(format.json{}
)は、@messagesをそのまま返すのではなく、JSONデータへ変換したデータをレスポンスしたいので、render json: @messages
を記述します。(このデータの中身は次のセクションで確認します。)
上記の画像のように、$.ajax()
で送信されるリクエスト形式はrequest.format
で確認したようにjsonなので、render json: @messages
の方を実行し@messagesをJSON形式に変換した情報をレスポンスします。
6.レスポンスを受け取りjQueryでViewに反映させよう
最後に以下の画像の①と②のように、Controllerからレスポンスを送信されたデータを受け取って、JavaScript(jQuery)で受け取ったデータを元にタイトル一覧に反映させます。
レスポンスを受け取る
$.ajax()
でリクエストを送信して通信が成功すると、以下のようにdone()
が実行されます。引数のdata
には、レスポンスで送信されたデータが格納されます。
1
2
3
4
5
6
$.ajax({
// リクエストの設定項目
)}
.done(function(data){ // dataにはレスポンスされたデータが入る
//通信に成功した際の処理
})
それでは以下のコードを追加して、通信が成功した際にdone()が実行されて引数dataにレスポンスデータが入るのか確認しましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$(function () {
$('.js-text_field').on('keyup', function () {
var title = $.trim($(this).val());
$.ajax({
type: 'GET',
url: '/messages/searches',
data: ("title=" + title),
dataType: 'json'
})
// 以下を追加
.done(function (data) {
console.log(data); // dataを確認する
})
});
});
以下の動画のように検索窓に「大切」と入力してConsoleを開くと、data
の中身は「検索窓の値を含んだタイトル」を持つメッセージの情報だと分かります。
そして、Controllerのrender json: @messages
で変換した通り、data
はJSON形式のデータになっていますね。
このdata
を上手く使えば、検索窓の値を含んだタイトル一覧の表示が出来そうですね。
jQueryでViewに反映させる
それでは、done()に処理を記述します。
通信が成功したら現在表示されているタイトル一覧は必要ないので、以下のコードを追加して削除します。
1
2
3
.done(function (data) {
$('.js-messages li').remove(); // 追加する
})
上記のコードを追加して検索窓に文字を入力すると、以下のようにjs-messages
のクラスを持つul
の中身(li
)が全て削除されます。
次に、以下のコードを追加して「レスポンスされたデータが入るdata
」を使って「削除したjs-messages
のクラスを持つul
要素の中身(li
要素)」を追加します。
1
2
3
4
5
6
7
8
9
10
.done(function (data) {
$('.js-messages li').remove();
// 以下のコードを追加する
$(data).each(function(i,message) {
$('.js-messages').append(
`<li class="message"><a href="/messages/${message.id}">${message.title}</a></li>`
);
});
})
上記はeach()
でdata
の中身を1つ1つ取り出し、js-messages
のクラスを持つul
要素にappend()
の引数に指定したli
要素を次々に追加します。
この記述によってjs-messages
のクラスを持つul
要素の中身は、以下のように検索窓に入力した内容に表示する事が出来ます。
これでAjaxを用いた「検索窓に文字を入力するたびにタイトルの候補を表示する」というインクリメンタルサーチをRailsとjQueryを使って実装する事が出来ました。
以下の画像を確認して、ここまで実装した流れを一回整理してみましょう。
手元に置いておきたい1冊
こちらの「プロを目指す人のためのRuby入門」は、Rubyの特徴から例外処理、デバック技法など実務で必要となる知識を一通り学ぶことができます。
Ruby on Railsは、Rubyで書かれたフレームワークです。Railsで使用される構文はRubyの構文が大半です。そのためRubyをしっかり学習することでRailsへの理解が深まります。
Rubyは触りだけでRailsの扱い方に学習時間を費やす、もしくはRailsから学習している方もいますが、いずれにしても並行してRubyを学ぶと良いでしょう。
豊富なサンプルコードと丁寧な解説でしっかり理解できるように書かれている良書です!
言語仕様からテスト駆動開発・デバッグ技法まで
補足
前のセクションまででAjaxを用いたインクリメンタルサーチの実装は大体終わりましたが、「通信が失敗した場合の処理」や「他のページから遷移した際のjQueryの挙動」などを確認していきます。
通信が失敗の場合の処理
Ajaxでリクエストを送信して成功した際の処理をdone()
で記述しましたが、以下のようにfall()
を使うと通信に失敗した際の処理を記述する事が出来ます。
1
2
3
4
5
6
7
8
9
$.ajax({
// リクエストの設定項目
)}
.done(function(data){
//通信に成功した際の処理
})
.fail(function(){
//通信に失敗した際の処理
})
もし、通信に成功しても失敗しても通信が完了した際に何か処理を実行したい場合は、以下のようにalways()
を使って処理を記述する事が出来ます。
1
2
3
4
5
6
7
8
9
10
11
12
$.ajax({
// リクエストの設定項目
)}
.done(function(data){
//通信に成功した際の処理
})
.fail(function(){
//通信に失敗した際の処理
})
.always(function(){
//通信が完了してdone()かfail()が実行された後に、always()が実行される
})
ページ遷移した際のjQueryの挙動
現在は、タイトル一覧ページに初回でアクセスした場合やリロードした場合にインクリメンタルサーチが正常に動く状態ですが、以下の動画のように他のページからタイトル一覧ページに遷移した場合はjQueryが上手く動かずに機能が使えない状態です。
上記は、デフォルトでturbolinks
というgemが入っているので$(function () {})
内に記述するコードが読み込まれないのが原因です。
これを解決するために、以下のmessages.js
のように$(function () {})
の外側にturbolinks:load
を設定します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$(document).on('turbolinks:load', function () { // このコードを追加する
$(function () {
$('.js-text_field').on('keyup', function () {
var title = $.trim($(this).val());
$.ajax({
type: 'GET',
url: '/messages/searches',
data: { title: title }, //("title=" + title),
dataType: 'json'
})
.done(function (data) {
$('.js-messages li').remove();
$(data).each(function (i, message) {
$('.js-messages').append(`<li class="message"><a href="/messages/${message.id}">${message.title}</a></li>`);
});
})
});
});
}); // このコードを追加する
上記のように記述する事で、初回アクセスやリロードだけではなく他のページから遷移しても処理が読み込まれて、正常に動作するようになります。
上記は、他のページからタイトル一覧ページにアクセスしてもインクリメンタルサーチが正常に動作していますね。
この記事のまとめ
$.ajax()
でリクエストを送信して通信が成功した場合は、done()
に記述した処理が実行される- レスポンスされるデータは、
done(function(data){})
の引数data
で受け取る事が出来る - Rails + jQueryでのAjax実装は、1つ1つの処理の流れを把握すると理解しやすい!