Minstrel

Ruby, JavaScript, Haskell, Math, Music, Design

【初心者向け】ajaxハンズオン with Rails5.1/ jQuery3.0

初心者向け

プログラミング学びたての方から、ajaxがよくわからないという相談を Web上を見るとajaxの詳しい解説はあっても、ハンズオン形式の記事は少ないと感じました。 ということで、細かい説明は抜きにしてとりあえず動くことを重視した記事を作成しました。

対象

ターゲット

  • Ruby on Rails学習中のプログラミング初学者(累計学習時間50h ~ 100h)
  • jQueryは少しだけ触ったことがある。

環境

  • Ruby on Rails(5.1系)
  • MySQL5.6 ※4系向けにも少し細くします。

作成するもの

最小限のTodo管理アプリを作成します。 細かいことは説明しない代わりに、はじめての方でも作りきれるように 過程を細かく載せていきます。

キーワード

gif

Image from Gyazo

完成系のコード(Ajaxの部分)

$(document).ready(function() {
  $("#submit").on('click', function(e) {
    e.preventDefault();
    var text = $('#task_title').val()

    $.ajax({
      type: 'POST',
      url: '/tasks.json',
      data: {
        task: {
          title: text,
        }
      }
    }).done(function(data){
      $('#task-list').append(
        `<tr>
          <td>
            ${data.title}
          </td>
        </tr>`
      )
    })

    $('#task_title').val('')
  })
})

1. アプリを作成する(rails new)

作成

rails new!

まずはアプリの型、作成からいきましょう。

rails newをしていきます。

rails new todo -d mysql

続いてデバッグ用に 'pry-rails' というgemをGemfileにいれておきましょう。

# Gemfile
gem 'pry-rails'
bundle install

scaffoldで簡単にアプリを作成しよう!

Railsにはscaffoldという、アプリケーションの枠組みだけをコマンド一発で作成してくれる機能があります。 今回はajaxの練習であるため、サーバーサイドの記述は極力簡略化するために、このscaffoldを使いましょう!

scaffoldについての詳細はこちら Rails scaffoldを初心者向けに解説!実際にアプリを…|Udemy メディア

以下のコマンドを順に実行しましょう!

rails g scaffold task title:string #todoモデルを作成(titleというカラムをもたせる)
rails db:create # データベース作成
rails db:migrate # マイグレーション実行

2. jQueryCDNでインストールする(Rails5向け)

CDNによるjQueryインストール

※Rails4には デフォルトでjQueryが入っているため、この作業は飛ばしてください。

まずは、jQueryの公式サイトにいきましょう! jQuery CDN

Image from Gyazo

jQuery 3.x のuncompressedを押すと表示されるリンクをコピーして、application.html.erbに貼り付けましょう! gyazo.com

3. jQueryの練習

JavaScriptファイルの作成

assets/javascripts 配下に tasks.js というファイルを作成しましょう! ※tasks.coffeeというファイルが自動生成されている場合は tasks.coffeeを削除してください。

$(document).ready(function() {})

tasks.jsに以下のように記述しましょう。

>||js||

$(document).ready(function() {

console.log("Hello World");

})

|

GoogleChromeの検証機能などで、確認しましょう!

Image from Gyazo

$(document).ready(function() {})

この記述については詳細は割愛しますが。 "DOM要素(HTML)を全てよみこんでから、JavaScript実行する"ための記述です。

4. Ajaxについて

HTMLを書き換える

index.html.erbを以下のように書き換えましょう
<p id="notice"><%= notice %></p>

<h1 id="title">Tasks</h1>

<!-- scaffoldで自動生成したformを呼び出しましょう -->
<%= render 'form', task: @task %>

<table>
  <thead>
    <tr>
      <th>Title</th>
      <th colspan="3"></th>
    </tr>
  </thead>
   
  <!-- jQueryでDOMを取得できるようidを付与しましょう -->
  <tbody id="task-list">
    <% @tasks.each do |task| %>
      <tr>
        <td><%= task.title %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>
_form.html.erbを以下のように書き換えましょう
<%= form_with(model: task, local: true) do |form| %>
  <% if task.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(task.errors.count, "error") %> prohibited this task from being saved:</h2>

      <ul>
      <% task.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= form.label :title %>
     <!-- idを付与しましょう -->
    <%= form.text_field :title, id: :task_title %>
  </div>

  <div class="actions">
    <!-- idを付与しましょう -->
    <%= form.submit "Submit", id: "submit" %>
  </div>
<% end %>
tasks_controllerを以下のように編集しましょう
class TasksController < ApplicationController
  def index
    @tasks = Task.all
    @task  = Task.new # _form.html.erbで使用する変数を定義
  end
end

onでイベント発火

JavaScript/jQueryでは〇〇を押したら~、◯◯の上にカーソルをのせたら、のようなタイミングをとることができます。 それをイベントの発火と呼びます。 「submitボタンを押したら、~~する 」を表すコードを on を使用して書いてみましょう。

tasks.jsを以下のように編集しましょう。
$(document).ready(function() {
  $("#submit").on('click', function(e) { //①
    e.preventDefault(); //②
    var text = $('#task_title').val() //③
    console.log(text)
  })
})

①'submit'というidがついたDOMがクリックされたときに、第二引数にあたえられた関数(function)を実行します ②e.preventDefaultはsubmitボタンがDefaultでもっているページ遷移しようとする機能をキャンセルします ③'task_title'というidがついたDOM(今回の場合はinput)のvalueを取得します

ajaxでリクエスト

ajaxでtasks_controller#createアクションにリクエストを送っていきましょう!

tasks.jsを以下のように編集します
$(document).ready(function() {
  $("#submit").on('click', function(e) {
    e.preventDefault();
    var text = $('#task_title').val()

    $.ajax({
      type: 'POST', // ①HTTPメソッドを指定します。
      url: '/tasks',    // ②パスを指定します
      data: {            // ③HTTPリクエストのボディを指定します。Railsではここで指定した値がparamsに入ります。
        task: {
          title: text,
        }
      },
      dataType: 'json' // ④HTTPリクエストで要求するdataのタイプを指定します。
    }).done(function(data){ // ⑤リクエストに成功した場合 .done以下の関数が実行されます。
      console.log(data)
    })
  })
})

④ dataType: 'json'

dataType: 'json' は 「リクエストでhtmlではなくjsonを返してね」という意味になります。 これはtasks_controller#createの以下と対応しています。

def create
    @task = Task.new(task_params)

    respond_to do |format|
      if @task.save
        format.html { redirect_to @task, notice: 'Task was successfully created.' }
        format.json { render :show, status: :created, location: @task } # ここ!
      else
        format.html { render :new }
        format.json { render json: @task.errors, status: :unprocessable_entity }
      end
    end
  end

format.json というのが、jsonを求めるリクエストが来た場合です。 今回の場合はhtmlではなくjsonという形式でレスポンスを返す記述となっています。 jsonを生成するためにjbuilder(show.json.jbuilder)というものが使われていますが、今回はjbuillderに関する記述は割愛します。 jbuilderはjsonを整形して生成するために必要なもの、ぐらいに抑えておいてください。

⑤ done

リクエストが成功した場合にdone以下に書かれた関数が実行されます またその際、引数にはレスポンスが入ってきます。このレスポンスを活用してこのあとHTMLを書き換えていきます。

$.ajax({
  省略
}).done( function(data) {
  console.log(data) // <- dataにレスポンスが入っている
})

HTMLを書き換える

最後にajaxで取得してきたレスポンスデータを使って TodoListを追加していけるようにHTMLを書き換えましょう!

$(document).ready(function() {
  $("#submit").on('click', function(e) {
    e.preventDefault();
    var text = $('#task_title').val()

    $.ajax({
      type: 'POST',
      url: '/tasks',
      data: {
        task: {
          title: text,
        }
      },
      dataType: 'json'
    }).done(function(data){
      $('#task-list').append( 
        `<tr>
          <td>
            ${data.title}
          </td>
        </tr>`
      ) // task_listに新しいtodoデータをつかった<td>を追加
    })

    $('#task_title').val('') // formの値をリセット
  })
})

こんな風にうごいたら完成です! Image from Gyazo

Reference

以下の記事を目に通すとよりajaxやjQueryへの理解が進みます。 とはいえ今はES6 + React/Vueなどのフレームワークの時代です。 かんたんなjQueryでDOM操作になれたあとは しっかりとJavaScriptの基礎を学び → ES6を学び → React/Vueなどのフレームワークに挑戦 もしていけるといいですね! もちろんjQueryも正しく使えばまだまだ使っていける技術だと思っています!

Ajaxについて https://qiita.com/zakiyamaaaaa/items/bdda422db2ccbaea60d9 jQueryによるDOM操作 https://qiita.com/nekoneko-wanwan/items/227ccad5f8cc449e91e9