2012-04-02 1 views
3

誰でも私がRailsアプリケーションで偉大な孫レコードの数を数えるのに役立つことができますか?例えばRailsアプリケーションで偉大な孫オブジェクトを数えるには?

、私は次のような何かをしたい:

class Country 
    has_many :states 
    has_many :cities, :through => :states 
    has_many :events, :through => :cities 
end 

class State 
    belongs_to :country 
    has_many :cities 
    has_many :events, :through => :cities 
end 

class City 
    has_one :country, :through => state 
    belongs_to :state 
    has_many :events 
end 

class Event 
    belongs_to :city, :counter_cache => true 
    has_one :state, :through => city, :counter_cache => true 
    has_one :country, :through => :state, :counter_cache => true 
end 

だから私は、各都市の、各状態のため、各国のイベントの数にアクセスできるようにしたいです。

私は市と州が働いていますが、祖父母国の偉大なモデルで実行されているcounter_cacheを取得できないようです。

私は何かを見逃しましたか?これは可能ですか?それを行うより良い方法はありますか?

コミュニティからいくつかのアイデアをいただければ幸いです。ありがとう!

答えて

1

あなたはカウンタキャッシュrailscastsのエピソードを見ましたか?それは役に立つかもしれません。

http://railscasts.com/episodes/23-counter-cache-column

いくつかのレベルを数えたい場合は、いくつかのステートメントを連結して答えを得ることができます。しかし、これを達成するために複数のDB呼び出しがあるため、これはひどく効率的ではありません。したがって、このカウントを頻繁に実行する場合は、カウントをキャッシュするほうがよいでしょう。

はここで何かのように、国のすべてのイベントの数を取得する例(未テスト)をです:

country = Country.find(params[:id]) 
number_of_events_in_country = 0 
country.states.each{|s| s.cities.each{|c| number_of_events_in_country += c.events.count}} 
+0

アドバイスノーマルでありがとうございます。私はカウンタをキャッシュすることをお勧めします。あなたは長い協会を数えることを試みたことがありますか?私の実装がなぜ機能していないのか分かりません。それは....そうなのだろうか?私が何か明白なものを見逃しているのだろうかと思います。 –

+0

ええ、私は 'has_many:through'を使って数えましたが、いくつかのレベルではない孫(孫だけではありません)に限られます。しかし、( 'app/models/country.rb')' has_many:events、:through =>:states'のようになり、 'app/models/state.rb'に相当する' has_many: =>:cities'、 'app/models/city.rb'には' has_many:events'があります。私はこの種の連鎖がうまくいくと思います。 – jefflunt

+0

キャッシュカウンタははるかに簡単です。したがって、 'event'が作成されると' event.city.update_attribute(:event_count_cache、event.city.event_count_cash + 1) 'のような処理が行われ、' event.city.state'の同様のカウントキャッシュの増分が続きます各レベルでカウンタをインクリメントします。もちろん、イベントが破棄された場合、キャッシュカウンタが逆の場合に更新され、イベントが都市を変更した場合、キャッシュカウンタはすべて新しいもので再インクリメントされたものであることを確認する必要があります都市/州など – jefflunt

1

それは(あなたが上記したように)あなただけの経由has_manyを使用することができ祖父母関係だ場合は、あなたは祖父母の偉大な関係を持っており、これはそれのためには機能しません。

親の子関係が複数ある場合は、あなたのカントリークラスにメソッドを入れて解析することができます。

class Country 
    has_many :states 
    has_many :cities, :through => :states 
    attr_accessor :events 

    def initialize 
    @events = Array.new 
    end 

    def get_events 
    self.states.each{|s| s.each{|c| c.each{|e| @events << e }}} 
    end 

end 

次に、get_eventsメソッドを呼び出すと、イベントには最初のレコードに関連付けられたすべてのイベントが設定されます。

usa = Country.first 
usa.get_events 
usa.events 
関連する問題