Has_many: через counter_cache
Насколько я понимаю, при определении параметра: counter_cache он должен быть указан в модели, которая включает объявление belongs_to. Поэтому я немного не уверен в том, как справиться с этим при работе с ассоциацией has_may (так как я полагаю, что объявление belongs_to не используется в этом сценарии):
class Physician < ActiveRecord::Base
has_many :appointments
has_many :patients, :through => :appointments
end
class Appointment < ActiveRecord::Base
belongs_to :physician, :counter_cache => appointment_count
end
class Patient < ActiveRecord::Base
end
Я хочу использовать параметр: counter_cache, чтобы сделать более доступным количество пациентов, принадлежащих к врачу.
myPhysician.patients.count
FYI: Rails 3.1
Приветствия
Ответы
Ответ 1
Я не уверен, какие отношения вы хотите. Этот пример аналогичен приведенному в Rails Guide
class Physician < ActiveRecord::Base
has_many :appointments
has_many :patients, :through => :appointments
end
class Appointment < ActiveRecord::Base
belongs_to :physician
belongs_to :patient
end
class Patient < ActiveRecord::Base
has_many :appointments
has_many :physicians, :through => :appointments
end
- A
Physician
имеет много Appointments
и имеет много Patients
- An
Appoinment
принадлежит (имеет один) Physician
и один Patient
- a
Patient
имеет много Appointments
и много Physicians
.
Что касается опции: counter_cache, в соответствии с принадлежностью к doc:
Если вы хотите, чтобы число Patients
принадлежало Physician
, вам понадобится:
class Appointment < ActiveRecord::Base
belongs_to :physician, :counter_cache => :patient_count
belongs_to :patient
end
И вам нужно написать миграцию, чтобы добавить столбец patient_count в таблицу Phyisicans
.
Однако для has_many через отношения Rails 3.1 автоматически обнаруживает столбец counter_cache, поэтому вам не нужно его указывать (удалите :counter_cache => :patient_count
). Если вы укажете его, ваш счетчик увеличится на два (это очень странно).
Кстати, кажется, есть некоторые проблемы с: параметром counter_cache в Rails 3.1, как указано здесь:
Учитывая все это, может быть, лучше всего написать собственный механизм счета с помощью обратных вызовов.
Надеюсь, это поможет:)
Ответ 2
Я добавил counter_cache
в has_many :through
ассоциации на Rails 5.1, и философия та же, что и для has_many
. Пример использования врача, назначения, пациента:
- добавьте в таблицу
physicians
целое число patients_count
в виде целого числа - добавьте кеш счетчика в модель соединения (назначение .rb):
belongs_to :physician, counter_cache: :patients_count
Примечание: ответ выше верен, этот ответ только подтверждает, что он работает на Rails 5.1.
Ответ 3
Я столкнулся с аналогичной проблемой, считая количество записей в двух глубоких отношениях. В вашем примере это будет количество пациентов для врача, а не количество назначений. (например, не считайте несколько назначений для одного пациента) Я не тестировал другие предлагаемые решения, но, похоже, они возвращают количество назначений.
Я не нашел способа сделать это в Rails 4, в первую очередь потому, что здесь нет belongs_to through:
После исчерпания нескольких бесплодных подходов я нашел gem counter_culture
. Это легко решило проблему, определив два глубоких отношения, которые нужно посчитать:
class Patient < ActiveRecord::Base
belongs_to :appointment
counter_culture [:appointment, :physician]
end
Добавьте поле счетчика в Physician с помощью:
rails generate counter_culture Physician patients_count
И вуаля! Теперь вы можете легко выполнять запросы activerecord, такие как:
Physician.order(patients_count: 'DESC')