レール。関連するテーブルの値の合計を含む「count」列を追加します
概要
カテゴリテーブルと問題テーブルがあります。
カテゴリモデル:
has_many :issues
問題モデル:
belongs_to :category
issue_count をコレクションの仮想属性として返すクエリを作成できます。
Category.left_outer_joins(:issues).select('categories.*, COUNT(issues.*) AS issues_count').group('categories.id')
ただし、次のように、カテゴリ テーブルの値として issues_count を格納する実際の列がテーブルに必要です。
id | name | created_at | updated_at | description | tags | issues_count
解決策
:counter_cache オプションを使用できます。
class Issue < ApplicationRecord
# NOTE: you can also override the default column name
# by specifying a custom column name in the counter_cache declaration instead of true
belongs_to :category, counter_cache: true
end
:counter_cache オプションは、belongs_to 宣言を含むモデルで指定されていますが、実際の列は、関連付けられた (has_many) モデルに追加する必要があります。これにより、category.issues_count フィールドが ActiveRecord によって自動的に更新されます。
このフィールドを追加し、既存のレコードを更新するには、移行を作成する必要もあります。
class AddIssuesCountToCategory < ActiveRecord::Migration[7.1]
def up
add_column :categories, :issues_count, :integer, default: 0
Category.reset_column_information
Category.all.each do |c|
Category.update_counters c.id, issues_count: c.issues.length
end
end
def down
remove_column :categories, :issues_count
end
end
また、Ryan Bates は、このトピックに関する RailsCasts の優れたエピソードを紹介しています。 #23 カウンターキャッシュ列