あなたは正しい軌道に乗っています。しかし、最初に小さなエラーに対処する必要があります。Rails は、指示しない限りカウンター キャッシュを更新しません。
class Chapter
belongs_to :script, :counter_cache => true
end
関連するすべてのチャプターの作成前および破棄後に @script.chapter_count を自動的に更新します。
残念ながら、関係を通じて対処する場合、物事はそれほど単純ではありません。Paragraph モデルのコールバックを通じて、関連するスクリプトの段落カウンターを更新する必要があります。
注意: 以下は、Chapter にも段落カウンターを保持することを前提としています。
章モデルに同じ理論を適用することから始め、段落数の列をスクリプト テーブルに適用します。
class PrepareForCounterCache < ActiveRecord::Migration
def self.up
add_column :scripts, :paragraphs_count, :integer, :default => 0
add_column :chapters, :paragraphs_count, :integer, :default => 0
Chapter.reset_column_information
Script.reset_column_information
Chapter.find(:all).each do |c|
paragraphs_count = c.paragraphs.length
Chapter.update_counters c.id, :paragraphs_count => paragraphs_count
Script.update_counters c.script_id, :paragraphs_count => paragraphs_count
end
end
def self.down
remove_column :scripts, :paragraphs_count
remove_column :chapters, :paragraphs_count
end
end
次に、関係を設定します。
class Script
has_many: chapters
has_many: paragraphs, :through => :chapters
end
class Chapter
has_many: paragraphs
belongs_to :script, :counter_cache => true
end
class Paragraph
belongs_to :chapter, :counter_cache => true
end
あとは、コールバックとしてスクリプト内の段落カウンターを更新するよう Paragraph に指示するだけです。
class Paragraph < ActiveRecord::Base
belongs_to :chapter, :counter_cache => true
before_save :increment_script_paragraph_count
after_destroy, :decrement_script_paragraph_count
protected
def increment_script_paragraph_count
Script.update_counters chapter.script_id, :paragaraphs_count => 1
end
def decrement_script_paragraph_count
Script.update_counters chapter.script_id, :paragaraphs_count => -1
end
end