I've got a use case where I need to query for Appointment
records based on their created_at
or their start_on
values. There are two types of appointments: 'Estimate' and 'GLA (go look at)' , represented by a type
field with values 0 and 1.
If the appointment is of type Estimate, the query needs to use the start_on
field - and if the appointment is a GLA, the query needs to use the created_at
field, as GLA's are not scheduled and don't have start_on values.
Right now, I'm querying the data using a Rails scope to filter down properties who've had their last appointment from and to a certain date like so (the following shows 'from'):
scope :last_appointment_from, ->(date, type) {
query = joins(:appointments)
query = query.where('appointments.start_on = (
SELECT MAX(appointments.start_on)
FROM appointments
WHERE appointments.property_id = properties.id)')
query = query.where('appointments.start_on >= ?', date)
query
}
But this only queries the start_on
value.
I've tried looking into doing GREATEST(MAX(start_on), MAX(created_at)) - but then I'm not sure how to know which field to know to use in the where('events.start_on >= ?', date)
part.
After typing this out, I thought of another possible workaround - to just create another database field that gets updated with the corresponding date on an active record callback based on what type of Appointment it is, called query_field
or something (and run a script to set that value for all existing records) - and that way I can just query on that one field?
Any thoughts/help is greatly appreciated!
Since you already have a type field, it could be a use case for STI, ie same SQL schema for the model but different behavior on the ruby side.
Note the "type" field may already be causing issues with rails that you may not have considered as this field generally is reserved specifically for Single Table Inheritance STI in rails.
If you use STI you could just write an accessor that pulls the correct field from the database and presents it for each model.
I think this approach should work assuming that no appointment should have a created_at
before its start_on
unless it is GLA
scope :last_appointment_from, ->(date, type) {
query = joins(:appointments)
query = query.where('GREATEST(appointments.start_on, appointments.created_at) = (
SELECT GREATEST(MAX(start_on), MAX(created_at))
FROM appointments
WHERE appointments.property_id = properties.id)')
query = query.where('GREATEST(appointments.start_on, appointments.created_at) >= ?', date)
query
}
I'm not very good with Rails but for the pure MySQL you could use a where like this:
WHERE ( (appointments.created_at > date AND appointments.type = 1) OR (appointments.start_on > date AND appointments.type = 0) )
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.