How do you count great grandson objects in a Rails application?
can anyone help me count the number of great grandchildren records in a Rails application?
For example, I want to do something like the following:
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
Therefore, I want to be able to access the number of events for each city, for each state and for each country.
I have City and State, but I can't seem to get the counter_cache that works on the grand grandent Country model.
Did I miss something? Is it possible? Is there a better way to do this?
I really appreciate some of the community ideas. Thank!
source to share
Do you observe that episode railscasts counter cache? This might be helpful.
http://railscasts.com/episodes/23-counter-cache-column .
If you just want to count multiple levels down, you can chain multiple operators to get an answer. However, this will not be terribly efficient due to multiple DB calls to achieve this, so it would be better to cache the account if you use this account frequently.
Here's an example of getting all events in a country (unverified), for example:
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}}
source to share
If it's a grandparents relationship, you can just use has_many
via (as you pointed out above), but you have a great relationship with your grandparents and it won't work for that.
One thing you could do (if you have multiple levels of parenting to child) is putting a method in your Country class to parse it.
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
Then just call the get_events method and the events will be populated with all the events associated with the first record.
usa = Country.first usa.get_events usa.events
source to share