Вы на правильном пути. Но сначала вы должны устранить небольшую ошибку. Rails не будет обновлять кеш счетчика, если вы не указали его.
class Chapter
belongs_to :script, :counter_cache => true
end
Будет автоматически обновлять @ script.chapter_count перед созданием и после уничтожения всех связанных глав.
К сожалению, все не так просто, когда имеешь дело: через отношения. Вам необходимо обновить счетчик абзацев связанного скрипта с помощью обратных вызовов в модели абзаца.
N.B .: Предполагается, что вы также хотите сохранить счетчик абзацев в главе.
Начните с применения той же теории к модели главы и столбца количества абзацев в таблице сценариев.
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