2

次の関係モデルがあります。

class Doctor
  has_many :appointmets
  # has attribute 'average_rating' (float)
end

class Appointment
  belongs_to :doctor
  # has_attribute 'rating' integer
end

doctor.average_rating予定が評価されるたびに設定するコールバックを設定したい、つまりrating予定テーブルの列が触れるたびに設定したい。

私はこれで試しました:

class Appointment
  after_update :update_dentist_average_rating, if: :rating_changed?
  # also tried with after_save 
private

  def update_dentist_average_rating
    ratings = Appointment.where(dentist_id: dentist.id).map(&:rating)
    doctor.average_rating = ratings.reduce(:+) / ratings.size if ratings.any?
    doctor.save
  end
end

しかし、うまくいかず、いつもappointment.dentist.average_rating戻っnilてきます。でコールバックが実行されているかどうかをテストできないようですappointment.save私は何が欠けていますか?

編集:これはアプリの流れです

  1. (Patient クラスの) ユーザーが、レーティング: nil といくつかの doctor_id で予約を保存します。
  2. アポイントメント.日付が過ぎている場合、アポイントメント.レートは、'' を介してフォームで編集または設定できます。
  3. 次に、予定を更新する必要があります.doctor.average_rating
4

1 に答える 1

3

このコールバックでそれを達成しましたが、それが最善の方法であるかどうかはわかりません:

after_save if: :rating_changed? do |apt|
  ratings = Appointment.where(doctor_id: 10).map(&:rating)
  doctor.average_rating = ratings.reduce(:+) / ratings.size if ratings.any?
  doctor.save!
end
于 2013-02-07T15:27:55.210 に答える