2009-12-02 7 views
0

에서 레일, 자동으로 연결을 계산하는, 당신이 할.이적 레일 협회와 마법의 수를

단락 모델에서 script_id 키를 사용하지 않고 의 단락 수를 계산하려면 어떻게해야합니까?

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 

어떻게 단락에 당신에게 자동으로 연관 스크립트를하고 레일의 자동 카운트를 사용하여 계산?

답변

1

당신은 올바른 길을 가고 있습니다. 하지만 먼저 작은 오류를 해결해야합니다. 레일스는 사용자가 지시하지 않는 한 카운터 캐시를 업데이트하지 않습니다.

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 

콜백으로 스크립트의 단락 카운터를 업데이트 할 단락을 이야기하는 것입니다.

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 
0

빠르고 간단한 방법은, 캐시를 사용하지 않고하는 것입니다 :

이상하다
class Script 
    has_many :chapters 
    has_many :paragraphs, :through => :chapters 
end 

script = Script.find(1) 
puts script.paragraphs.size #get the count 
+0

, 나는 script.paragraphs.size가 0 egal 때문에 이적 협회가 작동하지 않았다 생각했다. 그러나 script.paragraphs.length는 정확합니다. 그러나 나는 정말로 tiouse paragraphs_count, 자동 레일 수를 원합니다. – MickaelFM

+0

이것은 레일 기능 (has_many로 추가 된 메소드)입니다. counter_cache는 has_many : through에서 작동하지 않습니다. 왜냐하면 캐시가 belongs_to 측에서 구현되기 때문입니다. 직접 작성해야합니다. 예를 들면 다음과 같습니다. http://www.ruby-forum.com/topic/138094#614246 – MattMcKnight