has_many:通过counter_cache

b73*_*b73 20 ruby ruby-on-rails

我的理解是,在定义: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
Run Code Online (Sandbox Code Playgroud)

我希望使用:counter_cache选项来更有效地查找属于医生的患者数量.

myPhysician.patients.count
Run Code Online (Sandbox Code Playgroud)

仅供参考:Rails 3.1

干杯

jäv*_*ävi 27

我不确定你想要什么样的关系.该示例类似于Rails指南中的示例

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
Run Code Online (Sandbox Code Playgroud)
  • A Physician有很多Appointments,有很多Patients
  • 一个Appoinment属于(有一个)Physician和一个Patient
  • 一个Patient有很多Appointments很多Physicians.

关于:counter_cache选项,根据belongs_to doc:如果你想要Patients属于a 的数量,Physician你需要:

class Appointment < ActiveRecord::Base
  belongs_to :physician, :counter_cache => :patient_count
  belongs_to :patient
end
Run Code Online (Sandbox Code Playgroud)

您需要编写一个迁移来将patient_count添加Phyisicans表中.

但是,对于has_many通过关系,Rails 3.1似乎会自动检测counter_cache列,因此您不必指定它(删除:counter_cache => :patient_count).如果你指定它,你的计数器会上升两个(这很奇怪).

顺便说一句,似乎存在一些问题:Rails 3.1中的counter_cache选项,如下所示:

考虑到所有这些,也许最好的办法是使用回调编写自己的计数机制.

希望能帮助到你 :)

  • 一点点更新:自动检测`has_many:through`的计数器缓存已从Rails中删除:https://github.com/sgrif/rails/commit/f072980382db8cb64c09f63001ef805843db51c8 (8认同)

小智 6

我在Rails 5.1上添加了counter_cache一个has_many :through关联,其理念与之相同has_many.使用医生,预约,患者示例:

  1. patients_countphysicians整数形式添加到表中
  2. 将计数器缓存添加到连接模型(appointment.rb): belongs_to :physician, counter_cache: :patients_count

注意:上面的答案是正确的,这个答案只是证实它适用于Rails 5.1.