前提
Rails6で「ユーザーが作品を投稿でき、その投稿に対していいねをすることがきる」Webアプリを制作しています。
現在、デイリーランキング機能(1日にいいねされた数を集計し、その内いいねの数が多い上位6つを取得する)を実装している途中です。
そこでRSpecを使ってデイリーランキング機能のテストを行いたいのですが、RSpec内で使用するテストデータをFactoryBotRailsを使って生成する方法が分からず困っております。
実現したいこと
イメージとしては、以下の画像のような関係のテストデータを想定しています。
デイリーランキングのテストを行う必要があるため、いいね数が段階的に異なるデータを生成したいと考えています。
※ 線が増えると見辛くなるため数字の1517までは省略していますが、オレンジ線と同様にWorks 24までの数字にそれぞれ対応しています。
※ 画像の9~14の下線は無視してください。(ハイパーリンクとして認識してしまっているのですが、作図アプリの都合上消すことができなかったためです。)
ソースコード
モデルとアソシエーション
使用しているモデルとアソシエーションは以下の通りです。
user.rb
rb
1class User < ApplicationRecord 2 has_many :works, dependent: :destroy 3 has_many :likes, dependent: :destroy 4end
work.rb
rb
1class Work < ApplicationRecord 2 belongs_to :user 3 has_many :likes, dependent: :destroy 4end
like.rb
rb
1class Like < ApplicationRecord 2 belongs_to :user 3 belongs_to :work 4end
コントローラー
Likesコントローラーは以下の通りです。
likes_controller.rb
rb
1class Api::V1::LikesController < ApplicationController 2# 1日のいいねランキングから上位6つを取得 3 def get_top_6_in_daily_ranking 4 @daily_ranks = Work.joins(:user).includes(:user).select('works.*, users.url, users.name') 5 .find(Like.where(created_at: Time.current.all_day).group(:work_id).order('count(work_id) desc') 6 .limit(6).pluck(:work_id)) 7 render json: @daily_ranks 8 end 9end
(スピード優先のためファットコントローラーの状態のままになっています。
読みづらくて本当にすみません。)
Factory
likes.rb
rb
1FactoryBot.define do 2 factory :daily, class: Like do 3 sequence(:user_id) { |n| "#{n}" } 4 sequence(:work_id) { |n| "#{n}" } 5 created_at { Faker::Time.between(from: DateTime.now - 1, to: DateTime.now) } 6 updated_at { Faker::Time.between(from: DateTime.now - 1, to: DateTime.now) } 7 #association :user 8 end 9end
補足情報(FW/ツールのバージョンなど)
環境
- rails v6.0.3.6
- rspec-rails v4.0.2
- factory_bot_rails v6.1.0
あなたの回答
tips
プレビュー