Railsアプリ / 非同期通信
非同期通信とは
簡単に言うと、「画面が切り替わらずに処理が行われる仕組み」です。
非同期通信を使用する案件
ランサーズの"仕事を探す"から「非同期通信」というワードで検索をかけてみると、
11件見つかりました。
その中で、募集終了していますが、こんな案件がありました。
例えば、セレクトボックスで北海道を選択したら、それと連動して北海道の市町村だけが表示されるセレクトボックスが出現する・・・といった動きを非同期通信で実現したいという依頼内容です。
非同期通信を使った簡単なアプリ
案件とは異なる機能ですが、今回は非同期通信の実装がテーマなので、そんなアプリをRuby on Rails で作ってみます。
事前準備
作業用ディレクトリを作成する
「非同期通信」は英語で「asynchronous communication」なので、ディレクトリ名は、"asynchronous_communication"にします。
新規rails アプリを立ち上げる
今回は、非同期通信を実装したいだけなので、オプション指定は省こうと思います。
rails new . というコマンドをターミナルで打つと、現在いるディレクトリで新規railsアプリを立ち上げることができます。
ターミナルでrails s、ブラウザのアドレスバーにlocalhost:3000と打ち込んで、次の画面を表示させます。
ルーティング、コントローラー、ビューを設定する
config > routes.rb
localhost:3000にアクセスしたら、homesコントローラーのtopアクションが動くように、root "homes#top"を追記しました。
app > controllers > homes_controller.rb
controllersフォルダの中に、homes_controller.rbを新規作成して、中身は自作しました。
app > views > homes > top.html.erb
viewsフォルダの中に、homesフォルダを作成しました。
そして、homesフォルダの中に、top.html.erbを作成しました。
ローカルサーバーを再起動して、ブラウザを確認する
設定を読み込ませるために、ターミナルに「Ctrl + c → rails s」を打ち込んで、ローカルサーバーを再起動させます。
その後、ブラウザでlocalhost:3000にアクセスします。
このページで非同期通信を作っていきます。
完成形
gif動画を見てもらうと、画面がリロードせずに投稿ができていることが分かります。
この現象が起きてる裏側でどのような処理が起きているのかを書いていきます。
構成ファイル
まずは先ほどの処理を作り出しているファイル群を紹介します。
ルーティング
config > routes.rb
ビュー
app > views > homes > top.html.erb
コントローラー
app > controllers > posts.controller.rb
ジェイソンビルダー
app > views > posts > create.json.jbuilder
javascriptファイル
app > assets > javascripts > script.js
共通するhtmlファイル
app > views > layouts > application.html.erb
javascriptを読み込む処理が書かれています。
大まかな処理の流れ
次に、フォームにデータを入力して、Sendボタンを押すと、非同期通信が起こり、データが表示される・・・という現象の裏側で起こっている、データの処理の流れについて書いていきます。
createアクションが動く
まずは、form_withに書かれているurlに従ってpostsコントローラーのcreateアクションが動きます。
データベースにデータが保存される
コントローラーで、フォームから送られてきたparams[:text]を@postに代入し、保存しています。
submitイベントが発火する
#new_postはボタンに付いているidです。
以下の記述は、ボタンを押した時に実行されます。
})
通常のデータ送信を止める
e.preventDefault();によって、通常のデータ送信を止めています。
これによりjson形式でデータを送ることができます。
2種類の変数
・var formData = new FormData(this);
→javascriptのオブジェクトとしてフォームに入力されたデータを、formDataに代入しています。
・var url = $(this).attr('action')
→フォームのアクション属性を取得したものをurlに代入しています。
ajax通信がスタートする
processDataとcontentType
データをformDataで送るときは、どちらもfalseにしておきます。
json形式に振り分けられる
その後、respond_toでhtmlとjsonで処理を分けています。
今回は、通常のデータ送信を止めているので、jsonが動いています。
json語に翻訳される
ジェイソンビルダーで、フォームから送られてきたデータをjson形式に変換しています。
jsonをdoneメソッドで受け取りhtmlを組み立てる
2回目以降もボタンを押せるように
$('.form__submit').prop('disabled',false);
→デフォルトでは1回ボタンを押したら2回目以降は押せなくなってしまうので、それを停止しています。
おわりに
まだまだ非同期通信については、調べることがたくさんあると思ったので、いつか調べてまとめてみたいと思います。
参考URL
https://qiita.com/yuitnnn/items/b45bba658d86eabdbb26
新規Railsプロジェクトの作成手順まとめ
https://dotinstall.com/lessons/basic_rails_v3/41809
ドットインストール #09ルートパスを設定してみよう
https://prog-8.com/lessons/rails5/study/2
Progate Ruby on Rails5 学習コースⅡ 「データベースを使ってみよう」
https://qiita.com/Kta-M/items/254a1ba141827a989cb7
Railsを始めてsqlite3まわりのエラーで躓いている人たちへ
https://techtechmedia.com/form-with-rails/#form_with
【Rails】フォーム実装できる「form_with」について分かりやすく解説!