你在正确的轨道上。但首先你必须解决一个小错误。Rails 不会更新计数器缓存,除非您指示它这样做。
class Chapter
belongs_to :script, :counter_cache => true
end
将在创建之前和销毁所有相关章节之后自动更新@script.chapter_count。
不幸的是,通过关系处理事情并不是那么简单。您将需要通过段落模型中的回调来更新关联脚本的段落计数器。
注意:以下假设您也想在章节中保留一个段落计数器。
首先将相同的理论应用于章节模型,并将段落计数列应用于脚本表。
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
剩下的就是告诉段落更新脚本中的段落计数器作为回调。
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