Я думаю, что вы хотели бы сделать это подтолкнуть это к проверке на модели назначения.См. http://api.rubyonrails.org/classes/ActiveRecord/Validations.html#M001391.
В приведенном ниже фрагменте appt_range строит диапазон от времени начала до конца, и метод createate должен вызываться при создании / обновлении.
Возможно, что-то вроде.
class Appointment < ActiveRecord::Base
def appt_range
start_time..end_time
end
...rest of code...
protected
def validate
@appointments = Appointment.all(:conditions => { :date_of_appointment => date_of_appointment, :doctor_id => doctor_id})
errors.add_to_base("Appointment Conflict") if @appointments.any? {|appt| appt.appt_range.overlaps? appt_range}
end
end
, и тогда ваш контроллер будет иметь
def create
@appointment = person.appointments.new(params[:appointment]))
if @appointment.save
...
end
end
def update
@appointment = person.appointments.find(params[:id])
if @appointment.update_attributes(params[:appointment])
...
end
end
Но это, как говорится (и это проблема в вашем исходном коде, а также), есть условие гонки / проблема.Предположим, что у пациента есть приложение с 10:00 до 10:30, и он хочет переместить его в 10: 15-> 10:45.Обновление не будет выполнено, так как доктор на данный момент уже забронирован для пациента.Возможно, добавление Patient_id, а не текущий пациент, решит этот крайний случай, но ваши тесты должны охватить эту возможность.
Также я просто выкинул это из головы и не проверял, так что ваш пробег может отличаться (вы не указали версию рельсов ,, а из кода. смотрит на 2.3.x?).Но, надеюсь, это направит вас в лучшую сторону ..
Редактировать ...
Я создал приложение barebones / simple rails 2.3.8, чтобы проверить его, и оно работает надСоздайте.взгляните на http://github.com/doon/appt_test Я также включил базу данных разработчика.
rake db:migrate
== CreateAppointments: migrating =============================================
-- create_table(:appointments)
-> 0.0019s
== CreateAppointments: migrated (0.0020s) ====================================
Loading development environment (Rails 2.3.8)
ruby-1.8.7-p299 > a=Appointment.new(:patient_id=>1, :doctor_id=>1, :date_of_appointment=>'08/10/2010', :start_time=>" 2010-08-10 8:00", :end_time=>"2010-08-10 10:00")
=> #<Appointment id: nil, patient_id: 1, doctor_id: 1, date_of_appointment: "2010-08-10", start_time: "2000-01-01 08:00:00", end_time: "2000-01-01 10:00:00", created_at: nil, updated_at: nil>
ruby-1.8.7-p299 > a.save
Appointment Load (0.2ms) SELECT * FROM "appointments" WHERE ("appointments"."doctor_id" = 1 AND "appointments"."date_of_appointment" = '2010-08-10')
Appointment Create (0.5ms) INSERT INTO "appointments" ("end_time", "created_at", "updated_at", "patient_id", "doctor_id", "date_of_appointment", "start_time") VALUES('2000-01-01 10:00:00', '2010-08-07 22:20:33', '2010-08-07 22:20:33', 1, 1, '2010-08-10', '2000-01-01 08:00:00')
=> true
ruby-1.8.7-p299 > b=Appointment.new(:patient_id=>1, :doctor_id=>1, :date_of_appointment=>'08/10/2010', :start_time=>" 2010-08-10 9:00", :end_time=>"2010-08-10 11:00")
=> #<Appointment id: nil, patient_id: 1, doctor_id: 1, date_of_appointment: "2010-08-10", start_time: "2000-01-01 09:00:00", end_time: "2000-01-01 11:00:00", created_at: nil, updated_at: nil>
ruby-1.8.7-p299 > b.save
Appointment Load (0.4ms) SELECT * FROM "appointments" WHERE ("appointments"."doctor_id" = 1 AND "appointments"."date_of_appointment" = '2010-08-10')
=> false
ruby-1.8.7-p299 > b.errors['base']
=> "Appointment Conflict"
ruby-1.8.7-p299 > c=Appointment.new(:patient_id=>1, :doctor_id=>1, :date_of_appointment=>'08/10/2010', :start_time=>" 2010-08-10 11:00", :end_time=>"2010-08-10 12:00")
=> #<Appointment id: nil, patient_id: 1, doctor_id: 1, date_of_appointment: "2010-08-10", start_time: "2000-01-01 11:00:00", end_time: "2000-01-01 12:00:00", created_at: nil, updated_at: nil>
ruby-1.8.7-p299 > c.save
Appointment Load (0.3ms) SELECT * FROM "appointments" WHERE ("appointments"."doctor_id" = 1 AND "appointments"."date_of_appointment" = '2010-08-10')
Appointment Create (0.4ms) INSERT INTO "appointments" ("end_time", "created_at", "updated_at", "patient_id", "doctor_id", "date_of_appointment", "start_time") VALUES('2000-01-01 12:00:00', '2010-08-07 22:21:39', '2010-08-07 22:21:39', 1, 1, '2010-08-10', '2000-01-01 11:00:00')
=> true
и вот мой класс Appointment (я использовал метод validate: symbol)
class Appointment < ActiveRecord::Base
validate :conflicting_appts
def appt_range
start_time..end_time
end
private
def conflicting_appts
@appointments = Appointment.all(:conditions => { :date_of_appointment => date_of_appointment, :doctor_id => doctor_id})
errors.add_to_base("Appointment Conflict") if @appointments.any? {|appt| appt.appt_range.overlaps? appt_range}
end
end
Также в игре с этим, хотя в другом случае вы должны обязательно проверить.Пациент А имеет APT с доктором А от 10-11.Пациент Б имеет аппроксимацию с доктором А с 11-12.Они будут перекрываться в текущей реализации, так как они имеют общее число 11, и будут помечены как конфликтные.
Поэтому я не уверен, почему он не работает над созданием, если вы хотите показать свой код, мы можемпосмотри на это.
Хорошо, я понял, почему это не работает, и это связано с временем начала и окончания.Взгляните на это.
из тестирования ... (добавление регистратора внутри проверки показывает мне это).
appt.range == Sat Jan 01 09:06:00 UTC 2000..Sat Jan 01 21:10:00 UTC 2000 , my range = Tue Aug 10 09:15:00 UTC 2010..Tue Aug 10 14:19:00 UTC 2010
appt.range == Sat Jan 01 22:06:00 UTC 2000..Sat Jan 01 23:06:00 UTC 2000 , my range = Tue Aug 10 09:15:00 UTC 2010..Tue Aug 10 14:19:00 UTC 2010
appt.range == Sat Jan 01 09:30:00 UTC 2000..Sat Jan 01 12:14:00 UTC 2000 , my range = Tue Aug 10 09:15:00 UTC 2010..Tue Aug 10 14:19:00 UTC 2010
appt.range == Sat Jan 01 09:31:00 UTC 2000..Sat Jan 01 12:20:00 UTC 2000 , my range = Tue Aug 10 09:15:00 UTC 2010..Tue Aug 10 14:19:00 UTC 2010
То, что происходит, - это когда часть даты усекается иустановите значение 1 января 2000 г., когда вы извлекаете его из БД. Поэтому, когда вы выполняете запросы к базе данных, диапазоны не будут перекрываться, вы ищете даты в 2010 г. Создание времени начала / окончания для даты и времени решит проблему.вопрос, так как тогда дата будет снова значимой.Еще нужно изменить appt_range, чтобы скорректировать дату обратно на date_of_appointment.Это не происходит при обновлении, так как вы имеете дело со всеми данными из БД.так что все имеют одинаковую дату
см. http://github.com/doon/EMR/commit/b453bb3e70b5b6064bb8693cf3986cf2219fbad5
def appt_range
s=Time.local(date_of_appointment.year, date_of_appointment.month, date_of_appointment.day, start_time.hour, start_time.min, start_time.sec)
e=Time.local(date_of_appointment.year, date_of_appointment.month, date_of_appointment.day, end_time.hour, end_time.min, end_time.sec)
s..e
end
исправляет это путем принудительного начала и окончания времени с использованием date_of_appointment ...