https://qiita.com/Yuya-hs/items/6265f1aba1a73f38047a
の続きです。
上記記事の「準備」が済んでいる前提です。
曜日を表示して(月、火、水、木、金、土、日)、それに紐づいたデータをvueのテンプレートに表示する方法です。
テンプレート内にjavascriptのメソッドを記入することで実現します。
#実現したいこと
ユーザーが作成したanswerというモデルについて各曜日に何個のanswerを作成したか表示できるようにしたい。
完成イメージ(プログレスバーを使用しています)
#rails側の実装
//users_controller
def show
@wdays = ['(月)','(火)','(水)','(木)','(金)','(土)','(日)']
@contributions = current_user.answers.where(created_at: Time.current.all_week)
@contributions = @contributions.map{|days| I18n.l(days.created_at)}
end
@wdays はテンプレート上に表示し、同時にデータを検索するようの配列です。
@contributionsには例えば、「2021年11月07日(日) 21時09分50秒 +0900
2021年11月07日(日) 21時07分41秒 +0900
2021年11月03日(水) 21時43分22秒 +0900
2021年11月03日(水) 21時43分19秒 +0900」
という配列が保存されます。
json.days do
json.array! @wdays
end
json.contributions do
json.array! @contributions
end
json形式で上記コントローラーで取得した配列を変換し、vueで受け取れるようにします。
#Vue側での実装
<template>
<section v-for="day in days" :key="day" class="flex flex-row">
<span>{{day}}</span>
<progress :value="contributions.filter(n => n.includes(day)).length" max="30">
</progress>
<span>{{contributions.filter(n => n.includes(day)).length}}
</span>
</section>
</template>
<script>
import axios from 'axios';
export default {
name: 'Show',
data: function () {
return {
days: "",
contributions: ""
}
},
mounted() {
this.setUser();
},
methods: {
setUser: function () {
axios.get(`/api/users/${this.$route.params.id}`)
.then(response => {
this.days = response.data.days
this.contributions = response.data.contributions
})
}
}
}
</script>
データの受け取り方については今回の趣旨ではないので割愛します。
v-forで処理している「day」には曜日が収納されており、
contributions.filter(n => n.includes(day)).length
という埋め込まれたjavascriptによって例えばdayの中身が「(月)」の場合、
2021年11月07日(日) 21時07分41秒 +0900のような形で保存されている配列において月曜日のデータが何個あるかをカウントし、lengthによってそのカウントを表示できます。
@wdayが「月、火、水...」のように()なしで配列を作成してしまうと、「何月何日」の「月」と「日」をカウントしてしまうため()を付けています。