前提・実現したいこと
ユーザーの直近60日間での空きスケジュールの数をカウントする機能を作っています。
発生している問題・エラーメッセージ
sizeでカウントした空き日の数に誤差が出てしまいます。
例) 本当は空き日は1日
# helper.rb User.first.free_for_60_days.size →0 リレーションを使わないと正確に算出される(しかしN+1が起きる) User.first.where(free_on: Date.today..(Date.today + 29.days)).size →1
ソースコード
user_decorator.rb
def display_free_status free_dates_count = first.free_for_60_days.size if free_dates_count == 0 'nothing_free' elsif free_dates_count <= 5 'a_little_free' else free_dates_count > 5 'free' end end →0
user.rb
class User < ApplicationRecord has_many :free_days, dependent: :destroy has_many :free_for_60_days, -> { where(free_on_on: Date.today..(Date.today + 59.days)) }, class_name: 'FreeDay'
free_days.rb
class StockDay < ApplicationRecord belongs_to :user
cards_controller.rb
def index @cards = Card.all.page(params[:page]) if @target_date.present? @card = @card.includes(user: :free_days).where(user: {free_days: {free_on: @target_date }}) end if @target_area.present? @cards = @cards.includes(user: :cities).joins(user: :cities).merge(Users::City.where(city: @target_area.city)).distinct end @cards = @cards.includes(:free_for_60_days).decorate end
_cards.html.haml
- @cards.each do|card| .col-xs-12.col-md-3.col-sm-6.card-list .card{ class: "#{card.user.decorate.display_free_condition}"}
試したこと
includes→joinsに変更
@card = @card.includes(user: :free_days).where(user: {free_days: {free_on: @target_date }})
↑こちらを↓に変更したらきちんとfree_for_60_days.size
が適正な値(1)で算出されましたがN+1が発生してしまいました。
@card = @card.joins(user: :free_days).merge(FreeDay.where(free_on: @target_date)).distinct
おそらくincludes
のキャッシュに問題があると思うのですが解決方法がわかりません。どなたかご教授ください。
参考記事
has_manyをeager_load/includesするときの注意点
あなたの回答
tips
プレビュー