備忘録
テックエキスパートday21。今日はちょっとインプットが大量にあるので備忘録のみとなっています。
Rails でのAPIの実装方法
APIとはApplication Programming Interfaceで、まあアプリケーションをプログラミングで操作するためのインターフェイス的なところでしょうか。
で、そのAPIですが今の主流はデータをjson(JavaScript Object Notation)で返すのになっているらしくこれをjason APIとも言うそうです。(まあ覚えなくていいんですが)
で、このAPIをRailsに導入する方法は大きく3つあるようですが、最も簡単にできるのがHTMLを返すためのコントローラーと共用してAPIに使うというやり方。
HTMLを返すのかJSONを返すのか判断してくれるのがrespond_toメソッド
で、仮に最も簡単な方法「コントローラーを共用」する場合に問題になるのが「HTML返すの?jsonファイル返すの?」とコントローラーが迷ってしまう事。
しかしこれはrespond_toというメソッドを導入する事で自動的に判断してくれるらしい。レスポンスとしてhtmlが入っていれば○○を返す、jsonだったら○○を返すみたいな。
基本形
respond_to do |format|
format.html { render ... } # HTMLの時これ
format.json { render ... } # jsonの場合コレ
end
で、ここにレンダーがある通りレンダーで各ビューを読んでくるという感じ。で、この時htmlはそのままhtmlのビューとして結果を返しますがjsonの場合はハッシュの中に結果を入れた状態で返してくるよう。
参考記事:respond_to do |format|とはどの様な事をするのでしょうか?細かい詳細をお聞きしたく・・
なのでjsonの場合はビューファイルを作らなくても以下のような感じにすることも可能っぽい?
respond_to do |format|
format.json {
render json: { name: @name, nickname: @nickname }
}
end
ですが通常は下記のような感じでjsファイルを指定することになるよう。
def create
@user = User.new(user_params)
if @user.save
respond_to do |format|
format.html { redirect_to : }
format.json { render json: @user}
end
else
end
end
Ajaxによる非同期通信
何かを入力したら、再度ページが読み込まれて入力内容が反映されるのを「同期処理」というのに対し、googlemapやgmailのようにページが読み込まれることなく内容が反映される仕組みを非同期処理といいます。
で、これを可能にするのが Ajaxという仕組み。
非同期通信に関してはこちらの記事が詳しく分かりやすいので、基本的にここを参照して諸々噛み砕いていきます。
Ajaxは4つの機能による共同作業
で、このAjax何者という話なのですが簡単にいうと4つの機能を組み合わせることによって非同期通信を可能にするものです。
・XML HttpRequest
・Javascript
・DOME
・XML
XML HttpRequest
これはクライアントとサーバーの間でデータを伝送するための機能をクライアント側で提供する API のこと。
通常クライアントから要求されるとサーバー側でそれに対応するものを返しますが、XML HttpRequestはそれをクライアント側で完結しちゃうAPIということです。(なので非同期の肝はこれなんですね)
このAPIを使うのにJavascriptを用いる
で、このAPIを使うのにJavascriptが必要なのです。なぜならこのXMLなんとかというのがjavascriptの組み込みオブジェクトだから。
組み込みオブジェクトというのはプリセットされてるメソッドみたいなものですね。
DOMEによって書き換える場所を指定する
非同期通信をするにはXMLなんとかを使って、既存のWEBページ(HTMLとかXMLとか)情報を非同期に書き換える必要があります。
そんな時に必要なのは、まず「どこを書き換えるのか」を指定すること。ここで活躍するのが以前のブログでも登場したDOMEです。
XML
最後の何を書き換えるのか、で使われるのがXML(Extensible Markup Language)ですが、現在ではJSONを使うことが多いようです。テックエキスパートの教材でもXMLは使わずjsonでの処理となっています。
formData
非同期通信をフォームを使って行う際に、このFormDataを利用します。これは引数にthisを置くことで、フォームに入力された情報を取得できます。
var formdata= new FormData(this)とすることで、フォームに入力された情報をインスタンスとして「formdata」という変数に代入することができます。
ちなみにこの時のthisというのはfunctionで指定したセレクタ全体のことをさしています。
attrメソッド
これは要素が持つ属性を指定してそれを返すことができるメソッド。例えばurlを取得したい場合に「 var url = $(this).attr(‘action’)とすることで、フォームの送り先のURLなどを取得することができます。
jbuilder
railsには初期状態でjbuilderというgemが入っている。これは入力データをjson形式で出力できるテンプレートエンジンで「○○.json.jbuilder」ファイル内に出力したいものを入れればjsonで吐き出すことが可能。
またこの時、responde_toでrenderを指定する必要はなく、format.jsonだけでOK。
json.text @post.text
みたいな感じで、jsonとして出力したい値を右側に書く
非同期処理の結果をdoneで受け取る
jbuilderなどで指定した非同期処理の結果はdoneメソッドで受け取ることが可能。done(function(data※ここは任意?) { 処理 })
この「data」にはjson(サーバー側)から入ってくるデータが詰まっている。
テンプレートリテラル記法
なんかそういうのがあるらしく、バッククオーテーションで囲むことで式展開ができたり\nとかつけなくてもかいぎょうできたりするらしい。
参考記事:JavaScript の テンプレートリテラル を極める!
jsonデータを配列で取得する方法
json.array! @user do | user |にして以下に欲しい内容を入力すれば配列として取得が可能。らしい。
emptyメソッド
指定したdom要素の子要素のみを削除するメソッド。非同期処理で使えそうですね。ちなみにremoveメソッドは指定したDOM自体を削除するので注意。
参考記事:全部言えたらDOMマスター! HTML+DOMでノードを挿入する方法大全
for Eachメソッド
参考記事:【JavaScript入門】forEach文の使い方と配列の繰り返し処理まとめ!
Ajaxの手順!
では最後にajaxで非同期処理を実施する際の手順をまとめておきたいと思います。あくまで一例です。(入力フォームに入力された内容を非同期で出力するパターン)
①gemでjquery-railsを入れる
②application.jsにrequire jquery-railsを記載
③入力データを取得するためsubmitファンクション規定
④デフォルトファンクションを消すため、e.preventDefault設定
⑤データを受取るために、それを入れる変数を定義(data)など
⑥変数の値にはthisを入れる
⑦次にurlを取得する(データの送信先)
⑧attr(‘action’)で取れる
⑨ここまで来たら$.ajax({})でajaxをやる。urlとかtypeの指定
⑩それが出来たらコントローラーにデータがいっているはず
⑪アクションに対するテンプレを用意(jbuilder)
⑫jbuilderに読み込みたい数値を記載 json.text @post.textなど
⑬次はdoneの記述を書いていく。上手くいった時とfailの時で分ける
⑭doneにはなんらかの引数を入れる。ここにはjsonからのデータが入っている
⑮HTMLで入れ替える処理を書いていく。これは一番上のfunction直下
⑯変数html(仮)を定義し、returnでhtmlを返す
⑰アペンドしたい内容を考え記述
⑱doneに戻り、定義したurlを変数を使い持ってくる
⑲その上でアペンドを追加
$(function(){
⑮function buildUsert(user){
⑯ ⑰ var html = `ここは入れ替えたいhtml
return html;
}
③$('#セレクタ').on('submit', function(e){
④e.preventDefault();
⑤var formData = new FormData(this);⑥
⑦var url = $(this).attr('action');⑧
⑨ $.ajax({
url: url,
type: "user",
data: formData,
datatype: 'json',
processData: false,
contentType: false
})
⑬ .done(function(user){⑭
⑱ var html = buildUser(user);
⑲ $('.入れ替え先のセレクタ').append(html)
$('#セレクタ').val('')
})
.fail(function(){
alert('エラー');
})
})
});