#1 Rails × Vue.jsで動的なページをSPA化させる

さぁ、いよいよRailsとVue.jsを用いてSPA化させることにチャレンジするぞ、、、。
これは一週間、二週間くらいのチャレンジになりそう。。。
絶対達成させたい。。。。。！！！

実は以前、静的なページならそれっぽいSPAをしたことがあります。。。！！

それがこんな感じ。

![SPA.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653881/34f758bb-44ea-2e95-d178-3be17ba95692.gif)

「お問い合わせ」をクリックしたらすぐさま、お問い合わせページが表示される感じになってる。
これは静的なページを高速表示させているので、比較的簡単にできた。

問題は動的なページを高速表示させることができるかどうか。
railsで変数を定義して、データベースからデータを拾ってきて、
それをVue.jsに受け渡す的なことをやるのだろうか。。。

しっかりと頑張って実装できるように頑張ろう。

ってかその前にこれが果たしてSPAと呼ぶのか怪しい。SPAの定義を今一度確認してみる

# SPAとは

https://digitalidentity.co.jp/blog/creative/about-single-page-application.html

>SPAとは単一のWebページでアプリケーションを構成する設計構造の名称です。

単一のwebページのアプリケーションではないので、恐らく部分SPAだろう。

ま、なんとなくは分かるからとりあえず開発！

# Let's Go!!!

手始めにユーザーの投稿一覧ページ,users#showをVue.jsで実装できるように
作業していきます。

https://www.techpit.jp/courses/123/curriculums/126/sections/935/parts/3580
この有料教材を参考にして実装していきます。
有料なので、コピペではなく、この教材のコードを、僕が実際に作成したアプリのコードに置き換えて
実装していきます。
最近も某高額web制作、マーケティング教材のZ○NEが著作権違反疑惑
で炎上してるから、著作権には気をつけたい。。。。。

**config/routes.rb**

```rb
  namespace :api, format: 'json' do
    resources :users, only: [:show]
  end
```

namespace を使ってる理由は、URLやファイル構成を指定のパスにしたいらしい。
指定のパスにならない場合ってどんなときやろ。。。
指定のパスにすることで今後の実装が容易になるとか。

  namespace :api　と記載することで、コントローラーを作成する際は
apiディレクトリに作成します。

format: 'json'でコードjson形式に指定できる。
多分やりとりするデータがjson形式だとSPAができるイメージ。


```
$ rails g controller api/users

```

を実行。

**api/users_controller**

```rb
class Api::UsersController < ApplicationController
  def show
    @user = User.find(params[:id])
    @pagy,@drinks = pagy(@user.drinks.order('created_at DESC').includes(image_attachment: :blob))
  end
end
```

users_controllerにあることをそのままこっちにコピペしてきました。

フロントはVue.jsなのでgem 'pagy'、ページネーションを実装できるgemは使えないので、こう修正しましょう！

```rb
class Api::UsersController < ApplicationController
  def show
    @user = User.find(params[:id])
    @drinks = @user.drinks.order('created_at DESC').includes(image_attachment: :blob)
  end
end

```

json形式でデータのやりとりをします。
そんなときには、このjson作成を簡単にしてくれる、jbuilderというものがRailsには備わっているので、それを使ってjsonを返したいと思います。

```
touch app/views/api/users/show.json.jbuilder

```

を実行します。

**app/views/api/users/show.json.jbuilder**

```json

json.array! @drinks, :name , :price , :explain ,
                     :image , :region_id , :body_id , 
                     :acidity_id , :processing_id ,
                     :likes_count , :user_id
```

教材を参考にしてこのように書いてみました。
返ってくるデータが、配列なので、json.appay!と書くそうです。

name,price,explaineは、drinksテーブルのカラムです。そこにどんなコーヒーか、そのコーヒーは何円かといった情報がデータベースに保存されます。

したら

[{"name":"ddd","price":3000,"explain":"dddddd","image":{"name":"image","record":{"id":10,"name":"ddd","price":3000,"explain":"dddddd","user_id":7,"created_at":"2021-08-06T06:50:21.611Z","updated_at":"2021-08-06T06:50:21.649Z","region_id":1,"body_id":1,"acidity_id":1,"processing_id":1,"likes_count":null}},"region_id":1,"body_id":1,"acidity_id":1,"processing_id":1,"likes_count":null,"user_id":7},{"name":"SSS","price":3000,"explain":"ddddd","image":{"name":"image","record":{"id":9,"name":"SSS","price":3000,"explain":"ddddd","user_id":7,"created_at":"2021-08-06T06:50:05.971Z","updated_at":"2021-08-06T06:50:06.039Z","region_id":1,"body_id":1,"acidity_id":1,"processing_id":1,"likes_count":null}},"region_id":1,"body_id":1,"acidity_id":1,"processing_id":1,"likes_count":null,"user_id":7},{"name":"aaaaa","price":3000,"explain":"#sssss","image":{"name":"image","record":{"id":8,"name":"aaaaa","price":3000,"explain":"#sssss","user_id":7,"created_at":"2021-08-06T05:33:18.586Z","updated_at":"2021-08-06T05:33:18.657Z","region_id":3,"body_id":2,"acidity_id":3,"processing_id":2,"likes_count":1}},"region_id":3,"body_id":2,"acidity_id":3,"processing_id":2,"likes_count":1,"user_id":7},{"name":"サンプル","price":3000,"explain":"#ああああ","image":{"name":"image","record":{"id":7,"name":"サンプル","price":3000,"explain":"#ああああ","user_id":7,"created_at":"2021-08-06T05:32:54.357Z","updated_at":"2021-08-06T05:32:54.482Z","region_id":5,"body_id":2,"acidity_id":3,"processing_id":3,"likes_count":1}},"region_id":5,"body_id":2,"acidity_id":3,"processing_id":3,"likes_count":1,"user_id":7}]


このようにuserが投稿したデータが一瞬でjson形式で戻ってきました！
キターーーーーー！！！！
なんでだろう。。。。
railsがデータベースに問い合わせて、そのデータが一瞬でビューに表示できることがまじで不思議。
魔法みたい。

ここから非同期的に、データを取得したり作成したりを実装していきたいので

```

yarn add axios
```

を実行して行く感じ。

もうデータを一瞬で取得できてるからここから非同期で何かを処理する必要があるのか今の所わからない。。

つまりさっきの処理は同期的な処理だったってことかいな？

高速で表示されて、ページの一部分切り替わってもローディンされないなら非同期処理だろって思っていたんすよ。。。

ってことで調べてみる。

# 同期通信と非同期通信の違い

https://qiita.com/okamoto_ryo/items/d8d9476490a27ad17f71

同期通信は一般的な流れだった。

非同期はjsがサーバーとのやり取りを行って、それによって取得したデータをもとにHTMLを更新するらしい。この時、送受信するデータはHTMLではなくXMLで行われる。

>つまり、非同期通信では、リクエストを出してからレスポンスが返ってくるまでの間、ブラウザ上で他の処理を行い、サーバーからのレスポンスが返ってきた時にサーバー側から所得した情報をWebブラウザ(ビュー)上に表示するのである。

以前コメント機能を非同期処理で実装したことあったけど、
ビュー側の処理としては、打ったコメントを即座に表示させる処理。
rails側の処理としては、打たれたコメントをデータべースに保存する処理。
これを同時にしてたのね。。

以前は即座にデータベースに保存されていたのかと思ったけどそーゆー訳ではなく、
ビュー側でコメントを処理して表示させていたのねーーー。理解理解。

次回は受け取ったjsonデータをVue.jsで処理していきたいと思います！！！！