has_many: через counter_cache - PullRequest
       0

has_many: через counter_cache

20 голосов
/ 24 января 2012

Насколько я понимаю, при определении опции: counter_cache она должна быть указана в модели, которая включает в себя объявление own_to.Поэтому я немного не уверен в том, как справиться с этим при работе с has_may через ассоциацию (поскольку я считаю, что в этом сценарии не используется объявление own_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

К вашему сведению: Rails 3.1

Cheers

Ответы [ 3 ]

26 голосов
/ 08 февраля 2012

Я не уверен, какие отношения вы хотите. Этот пример аналогичен приведенному в 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
  • Appoinment принадлежит (имеет один) Physician и один Patient
  • a Patient имеет много Appointments и много Physicians.

Относительно параметра: counter_cache, в соответствии с own_to 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 , как сообщается здесь:

Учитывая все вышесказанное, возможно, вам лучше всего написать собственный механизм подсчета с помощью обратных вызовов.

Надеюсь, это поможет:)

5 голосов
/ 19 марта 2018

Я добавил counter_cache в has_many :through ассоциацию на Rails 5.1, и философия такая же, как с has_many. Пример использования врача, назначения, пациента:

  1. добавить patients_count к таблице physicians как целое число
  2. добавить кеш счетчика в модель соединения (назначение.rb): belongs_to :physician, counter_cache: :patients_count

Примечание: ответ выше верен, этот ответ только подтверждает, что он работает на Rails 5.1.

0 голосов
/ 17 января 2019

Я столкнулся с подобной проблемой, считая количество записей в двух глубоких отношениях.В вашем примере это будет количество пациентов для врача, а не количество назначений.(например, не считайте несколько встреч для одного пациента) Я не тестировал другие предлагаемые решения, но, похоже, они возвращают количество встреч.

Я не нашел способа сделать это в Rails 4, в первую очередьпотому что нет опции belongs_to through:.Исчерпав несколько бесплодных подходов, я нашел gem counter_culture.Это легко решило проблему, определив две глубокие отношения для подсчета:

class Patient < ActiveRecord::Base
  belongs_to :appointment
  counter_culture [:appointment, :physician]
end

Добавьте счетчик поля к врачу с помощью:

rails generate counter_culture Physician patients_count

И вуаля!Теперь вы можете легко выполнять запросы activerecord, например:

Physician.order(patients_count: 'DESC')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...