1

Rails で関連付けを自動的にカウントするには、次のようにします。

class Script
  has_many :chapters
end
class Chapter
  belongs_to :script
end

そして、スクリプト モデルに chapters_count 列を追加します。

では、段落モデルに script_id キーを持たずに Script の段落数をカウントしたい場合はどうすればよいでしょうか?

class Script
  has_many :chapters
  has_many :paragraphs # not complete
end
class Chapter
  has_many :paragraphs
  belongs_to :script
end
class Paragraph
  belongs_to :chapter
end

Rails の自動カウントを使用してスクリプトを段落に自動的に関連付け、それらをカウントするにはどうすればよいですか?

4

2 に答える 2

1

あなたは正しい軌道に乗っています。しかし、最初に小さなエラーに対処する必要があります。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
于 2009-12-02T22:07:38.327 に答える
0

キャッシュを使用せずにすばやく簡単に行う方法は次のとおりです。

class Script
  has_many :chapters
  has_many :paragraphs, :through => :chapters
end

script = Script.find(1)
puts script.paragraphs.size #get the count
于 2009-12-03T04:44:14.557 に答える