質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.39%
Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

0回答

671閲覧

Ranking機能を実装したい(親モデル・子モデル・孫モデルを用いて)

Ms.suger

総合スコア3

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2021/12/23 16:07

編集2021/12/23 23:38

皆様のお力添えをいただけないでしょうか?
現在、ダイエットのためのレコーディングを行えるサイトを作成しています。

###行いたいこと(概要)
①Workoutをした順位
②体重を減らした順位(基準は月曜を週初めとした区切りで、前週の最後の記録から最新を引いた値)
③目標体重に近づいた順位を
①②は日間と週間ごとのランキングを、③は週間と月間のランキングを出したいと考えています
######▼条件
・週間は月曜始まりと考えます
①の順位の対象は消費カロリーの合計を降順
②の順位の対象は前週・前月の(最後の記録 - 最新の記録)、もしくは該当する(期間内の一番古い記録 - 最新の記録)を引いた値を降順(どちらでも問題ありません)
③の順位の対象は(目標体重ー該当期間の一番古いデータ)-(目標体重ー該当期間の一番最新のデータ)の値をを降順

前提といたしまして、Workoutにはdateカラムはなく、Record のDateを基準にできればありがたいです
(日を跨いでの記録が存在すること等を考慮)。

###テーブル・モデル・アソシエーション
*不要な箇所は省略いたします

User model

カラム名データ型
namestring

Record model

カラム名データ型
user_idinteger
weightfloat
datedate

Workout model

カラム名データ型
record_idinteger
caloriedate

Aim model

カラム名データ型
user_idinteger
aim_weightfloat

#####アソシエーション
User
has_one :aim
has_many :records, dependent: :destroy
has_many :workouts, through: :records

Records
has_many :workouts, dependent: :destroy
belongs_to :user

Aims
belongs_to :user

###行った作業・状況
①について
(1)Workoutをした順位のみ下記URLの記事を参考に実装してみましたが、うまくいきませんでした。
・そもそもSQLの実装をしていません。railsへのSQL直書きについて調べ、実施してみましたがうまくいきませんでした。
(Syntax Errorが出ます)
・Viewの記述も自信がありません(参考記事がSilmの記述だったため調べながら実施しましたが、確認以前に上記のエラーが出るため確認できてません)

ruby

1WoRankingsController 2 def monthly 3 if params[:pre_preview].present? 4 @target_month = Date.parse(params[:pre_preview]) << 1 5 elsif params[:next_preview].present? 6 @target_month = Date.parse(params[:next_preview]) >> 1 7 else 8 @target_month = Time.current.to_date << 1 9 end 10 11 @wo_ranks = Record 12 .joins(:workouts) 13 .select("records.member_id 14 ,sum(workouts.burned_calorie) as workout_calorie 15 ,to_char(records.date,'YYYY') as workout_year 16 ,to_char(records.date,'MM') as workout_month 17 ,round(sum(workouts.burned_calorie),1) as total_workout 18 ,RANK () OVER (PARTITION BY to_char(records.date,'YYYY'),to_char(records.date,'MM') 19 order by (sum(workouts.burned_calorie) desc) as rank_number") 20 .where(study_date: @target_month.all_month) 21 .group("to_char(records.date,'YYYY') 22 ,to_char(records.date,'MM') 23 ,record.member_id") 24 .order("(sum(workouts.burned_calorie))desc)") 25 @my_rank = 0 26 @wo_ranks.each do |wo_rank| 27 if wo_rank.member_id == current_member.id 28 @my_rank = wo_rank.rank_number 29 break 30 end 31 end 32 end 33 34 35 end 36 37 def daily 38 39 if params[:pre_preview].present? 40 @target_month = Date.parse(params[:pre_preview]) << 1 41 elsif params[:next_preview].present? 42 @target_month = Date.parse(params[:next_preview]) >> 1 43 else 44 @target_month = Time.current.to_date << 1 45 end 46 47 @wo_ranks = Record 48 .joins(:workouts) 49 .select("records.member_id 50 ,sum(workouts.burned_calorie) as workout_calorie 51 ,to_char(records.date,'YYYY') as workout_year 52 ,to_char(records.date,'MM') as workout_month 53 ,to_char(records.date,'DD') as workout_day 54 ,round(sum(workouts.burned_calorie),1) as total_workout 55 ,RANK () OVER (PARTITION BY to_char(records.date,'YYYY'),to_char(records.date,'MM') ,to_char(records.date,'DD') 56 order by (sum(workouts.burned_calorie) desc) as rank_number") 57 .where(study_date: @target_month.all_month) 58 .group("to_char(records.date,'YYYY') 59 ,to_char(records.date,'MM') 60 ,to_char(records.date,'DD') 61 ,record.member_id") 62 .order("(sum(workouts.burned_calorie))desc)") 63 @my_rank = 0 64 @wo_ranks.each do |wo_rank| 65 if wo_rank.member_id == current_member.id 66 @my_rank = wo_rank.rank_number 67 break #breakとは? 68 end 69 end 70 end

view/monthly.html

ruby

1メインタイトルは、controllerの変数を参照して動的に作成 2<%# @page_title = "ランキング【#{@target_month.year.to_s}{@target_month.month}月度】" %> 3<div class="col-md-6 mx-auto"> 4 <div class="form-inline mb-3 justify-content-around"> 5<ボタンの作成controllerにパラメータを渡す 6 <%= link_to wo_rankings_monthly_path(pre_preview: @target_month), do %> 7 <i class="fa fa-chevron-leht"></i> 8 <%end%> 9 <span class="ml-2 mr-2 lead"> 10 <strong> <#%=@page_title %> </strong> 11 </span> 12<ボタンの作成controllerにパラメータを渡す 13 <%#= link_to wo_rankings_monthly_path(next_preview: @target_month), do %> 14 <i class="fa fa-chevron-leht"></i> 15 <%#end%> 16 </div> 17 <div class="text-center"> 18 もし期間中に自分の実績があれば、順位を表示する 19 <%# if @my_rank == 0 %> 20 <th>あなたはこの期間の実績がありません</th> 21 <%# else %> 22 <%("あなたの順位は #{@wo_ranks.size}人中") %> 23 <strong> <%#=(" #{@my_rank}位 ") %> </strong> 24 <%= ("です") %> 25 <%# end %> 26 </div> 27 28 <table class="table table-hover table-bordered"> 29 <theard class="thead-light"> 30 <tr class="text-center"> 31 <th>Ranking</th> 32 <th>neme</th> 33 <th>total</th> 34 </tr> 35 </thead> 36 <tbody> 37 ランキングは100位までとし、100位までループ 38 <%# @wo_ranks.limit(100).each_with_index do |rank,i| %> 39 <tr> 40 <td class="text-center"> 41 1位〜3位の場合は、順位に王冠を表示する 42 <% if wo_rank.rank_number != 1 && wo_rank.rank_number != 2 && wo_rank.rank_number != 3 %> 43 <%#= (wo_rank.rank_number) %> 44 <% end %> 45 <%= (wo_rank_image(wo_rank.rank_number) %> 46 </td> 47 <div class="form-inline"> 48 <% member = Member.find(wo_rank.member.id) %> 49 <td> 50 <%# link_to(member_path(member)) do %>< 51 <%# member.name%> 52 <%# end %> 53 </td> 54 </div> 55 <td class="text-right"> 56 <%#=format("%.1f",rank.study_total))) %> 57 </td> 58 </tr> 59 <%# end %> 60</tbody> 61</table> 62</div> 63 64

###参考記事
https://qiita.com/nekojoker/items/0e65509837550c140938
https://qiita.com/takaaaaaaaya/items/a293b6b0db713320cdcd

②、③ についてはデータの引っ張ってき方や、差分を出す記述がわかりませんでした。

せめて①だけでも実装できないかと考えています。
上記 の方向性から外れていても構いません。

初心者のため、拙い文章であるかつ根も葉もない質問であることは重々承知なのですが、
何かヒントをいただけないでしょうか?
よろしくお願いいたします

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.39%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問