Как посчитать объекты великого внука в приложении Rails? - PullRequest
4 голосов
/ 02 апреля 2012

Может ли кто-нибудь помочь мне подсчитать количество записей великих внуков в приложении 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 для прадедаМодель страны.

Я что-то пропустил?Это возможно?Есть ли лучший способ сделать это?

Я действительно ценю некоторые идеи от сообщества.Спасибо!

Ответы [ 3 ]

2 голосов
/ 02 апреля 2012

Вы смотрели эпизод с подсчетом тайников Railscasts?Это может быть полезно.

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

Если вы просто хотите отсчитать несколько уровней вниз, вы можете связать несколько утверждений, чтобы получить ответ.Тем не менее, это не будет очень эффективно, потому что для этого нужно несколько вызовов БД, поэтому было бы лучше кэшировать счет, если вы собираетесь часто его использовать.

Вот пример получения количества всех событий в стране (не проверено), что-то вроде:

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}}
1 голос
/ 30 августа 2012

Если это отношения прародителя, вы можете просто использовать has_many через (как вы перечислили выше), но у вас есть отношения прародителя, и это не сработает.

Единственное, что вы можете сделать (если у вас есть несколько уровней родительских и дочерних отношений), это поместить метод в ваш класс Country для его анализа.

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 
0 голосов
/ 15 февраля 2019

Я пытался понять это. Просто нажали на ссылку RailsCasts в ответе Джеффа и нашли этот 6-летний комментарий .

По сути, вы можете делать то, что вы хотите, используя многоуровневые функции кэширования counter_culture gem , передавая ему массив родителей и возвращаясь к вершине. Очевидно, что добавьте соответствующие столбцы как обычно.

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

  counter_culture [:city, :state, :country]
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...