複数のインスタンス変数をjson形式に変換する方法を✅
「13時間」MVP完成までに残された可処分時間。思いの外技術的負債が多くて無理なんじゃないかと焦っていることスバルです。
今回は複数のインスタンス変数をjson形式に変換してVueファイルで使う方法を✅していきます。
コントローラーにSQLをいっぱい書いてしまいfatになることってよくありますよね。僕もそうなりかけたので、うまい具合にmodelに切り出してfat controllerを防いでいきたいと思います。
「modelで作成したscopeをcontrollerに呼び出し、jsonに変えてから、vueで使いたい。」
これを実現していきたいと思います。以下いきなり独り言モードに入りますが、嫌いにならないでください。
scopeを作成
「Alcoholモデルのalcohol_percentageの値が7以下、7以上それぞれランダムで5つ取り出す」
これを実現するスコープは以下の通り。
class Alcohol < ApplicationRecord
scope :random_weak, -> { where('alcohol_percentage < ?', 7).sample(5) }
scope :random_strong, -> { where('alcohol_percentage > ?', 7).sample(5) }
end
controllerで呼び出す。
モデルファイルで定義したスコープはコントローラーにそのまま呼び出すことができる。一覧表示を担うindexアクションに記載する。N + 1問題は無視。
module Api
module V1
class AlcoholsController < ApplicationController
def index
@weak_alcohols = Alcohol.all.random_weak
render json: @weak_alcohols
end
end
end
end
複数のインスタンス変数をjsonに変える
モデルで作成したscope二つをコントローラーで使用したい。
respond_toを使って繰り返し処理を行うと複数のインスタンスをjsonに変換することができる。
module Api
module V1
class AlcoholsController < ApplicationController
def new
Alcohol.new
end
def index
@weak_alcohols = Alcohol.all.random_weak.sort do |a, b|
b[:alcohol_percentage] <=> a[:alcohol_percentage]
end
@strong_alcohols = Alcohol.all.random_strong.sort do |a, b|
a[:alcohol_percentage] <=> b[:alcohol_percentage]
end
respond_to do |format|
format.json do
render json: { weak_alcohols: @weak_alcohols,
strong_alcohols: @strong_alcohols }
end
end
end
end
end
end
Alcohol.all.random_weak.sort do |a, b|
b[:alcohol_percentage] <=> a[:alcohol_percentage]
end
この部分で、random_weakで取得したAlcoholデータをソートしている。
スコープを使わない状態に戻したら下記のようになる。長い。
Alcohol.all.where('alcohol_percentage < ?', 7).sample(5).sort do |a, b|
b[:alcohol_percentage] <=> a[:alcohol_percentage]
end
vueで呼び出す
サーバーに保存されているデータは、axiosを使い、apiを叩いて持ってくる。
<template>
<div>
{{ alcoholAll }} #...3
</div>
<h1 class="text-center" style="font-size: 50px">
酩酊に向けた酒ケジュール
</h1>
</template>
import axios from '../plugins/axios';
export default {
data: function () {
return {
alcohols: [],#...1
}
}
mounted() {
axios.get('/alcohols').then((alcoholResponse) => (this.alcohols = alcoholResponse.data)); #...2
},
computed: {
alcoholAll (){ #...3
const alcoholAll = this.alcohols["weak_alcohols"];
return alcoholAll;
},
}
}
- data()に、apiを叩いて持ってきたデータを格納するためのalcoholsを用意している。
- mountedは、DOM構築後に発火するライフサイクルフック。非同期処理はDOM構築前にやっても変わらないため、サーバーにアクセスする負担軽減のためにcreatedフックで行われることが推奨されているみたい。
- computedにデータを返すメソッドを記述することで、リアクティブにデータを表示することができる。定義したメソッドは、双方向バインディング( {{}}で囲まれている部分。)を使うことで、HTMLに表示することができる。
結果
こんな感じで「Alcoholモデルのalcohol_percentageの値が7以下、7以上それぞれランダムで5つ取り出す」を実現することができた。
今日の酒ケジュール
今日はバイト先の飲みに参加します。
できれば今日までにアプリを完成させて、この飲み会に向けた酒ケジュールを作りたかったのですが叶わず、、
ちなみに今日のスタンスは、「ほろ酔い」です。
酒ケジュールは以下の通り
これでバッチリほろ酔いになれます。それでは、楽しい週末を。