Presentación
Tengo un modelo al que llamaremos, en un alarde de originalidad, A.
Dicho modelo, tiene una relación tipo
has_many
con otro modelo que, para no destrozar el flow, llamaremos B. Este modelo B, tiene un campo de tipo date
llamado turn_date (aquí, el lector avezado, habrá podido intuir que el campo turn_date, representa la fecha de un turno.)Lo que quiero es realizar una búsqueda con thinking sphinx, de forma que los elementos de A que tengan algún turno en el día actual me aparezcan primero.
Nudo
Para entendernos más fácilmente pongamos un ejemplo concreto: estamos haciendo una web donde se muestran los turnos de los hospitales en Cataluña para que, en el caso de que sufras un infarto, puedas saber a cuál tienes que ir (no vaya a ser que llegues media hora antes del cierre y no te puedan atender).
Así, pues tendríamos los modelos
Hospital
, y HospitalTurn
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Hospital < ActiveRecord::Base | |
has_many :turns | |
end | |
class HospitalTurn < ActiveRecord::Base | |
#with a turn_date field of type date | |
end |
Lo que queremos es mostrar los resultados de una búsqueda, de forma que los hospitales que presten servicio en el día actual aparezcan primero.
Bien, ¿cómo hacemos esto?
Suponiendo que tenemos thinking sphinx configurado (y funcionando) habría que crear un atributo que represente si un hospital tiene algún turno que coincida con el día de hoy.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Hospital < ActiveRecord::Base | |
has_many :turns | |
define_index do | |
#lots of definitions here | |
has "(SELECT COUNT(DISTINCT hospital_id) FROM hospital_turns WHERE turn_date = CURDATE() AND hospitals.id = hospital_id)", :as => :emergency_service_today, :type => :integer | |
end | |
end |
De esta forma hemos creado un atributo que valdrá 1 si existe un turno de guardia para este día, o 0 en caso contrario.
Desenlace
Ahora para realizar una búsqueda y ordenar por el criterio que queremos, es decir, mostrar primero los hospitales que dan servicio hoy, bastaría con hacer:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Hospital.search(search_query, {:order => 'emergency_service_today DESC'}) |
Y ya por último, sólo nos quedaría asegurarnos, por medio de un cron de que cada día a las 00:00 se reindexa nuestro bienamado sphinx... y, por supuesto, esperar no sufrir ningún infarto a partir de las 17:00 en Tarragona.
Créditos
Gracias a Javier Ramirez, que es el que me dio la solución a este problema.
Ahora con internet los niños se te educan solos. -- Hommer J. Simpson
De nada ;)
ResponderEliminar