¿Cuál es la manera más rápida y estándar de "masar búsqueda" un conjunto de nietos (has_many, has_many) pertenecientes a un solo objeto?
Caso de uso: en este sitio, los usuarios podrán continuar y seleccionar la propiedad de alquiler por una cantidad específica de días. Los usuarios a menudo estarán vendiendo el mismo tipo de propiedad de alquiler.
Problema: Debido a que múltiples "vendedores" se alquila el mismo artículo exacto, la "página de detalles de propiedad" se tienen muchos listados creados por muchos vendedores diferentes (o en algún caso, un vendedor tendrá múltiples propiedades disponibles cayendo en la misma "página de detalles de propiedad"). Cada uno de estos objetos de "listings" tienen muchos pricing objetos que contienen una fecha, un precio y una disponibilidad booleana.
Los modelos actuales se desglosan a continuación:
property.rb
has_many :listings
has_many :prices, :through => :listings
listado.rb
belongs_to :user
belongs_to :property
has_many :prices
precio.rb
belongs_to :listing
Lo que he intentado:
Si, por ejemplo, quisiera obtener la suma del MINIMUM de precios para una propiedad específica, había tropezado con esto:
# property.rb
# minimum price for a pricing set out of all of the price objects
def minimum_price(start_date, end_date)
# this would sum up each days pricing to give the rental period a final price
prices = self.prices.where("day <= ?", end_date).where("day >= ?", start_date).sum(:price)
end
Cuando lo hago así, sin embargo, simplemente combina cada uno de los precios de los usuarios dando nada de uso.
Cualquier ayuda sería muy apreciada! Por supuesto que podría bucle a través de una lista de propiedades hasta que encontré un precio mínimo fijado para un rango de fecha dado, pero eso parece que tomaría una cantidad innecesaria de tiempo y sería en gran medida ineficiente.
EDITUn ejemplo de datos que deben ser producidos es un conjunto de objetos de precio que son los más baratos en un rango de fecha específico de la lista de ONE en particular. No sólo puede combinar todas las fechas mejor precio de todos los usuarios y añadirlas como el comprador se alquilará de ONE vendedor.
Este es un ejemplo real de la salida deseada, ya que puede ver estos precios son TODOS del mismo ID de listado.
[#, #, #, #]
Pregunta hecha hace 3 años, 4 meses, 28 días - Por quantumcoder403a
3 Respuestas:
-
Así que parece que estás llamando a esto en una propiedad así que:
prices = self.prices.where("prices.day >= ? AND prices.day <= ?", start_date, end_date).sum(:price).group_by {|price| price.listing_id}
Probablemente hay una forma basada en SQL que puede utilizar relaciones AR para hacer esto. Pero esto le dará un hash con una clave para cada list_id y el valor de esa clave debe ser la suma. Yo digo "debería" porque esto es un poco abstracto para mí para hacer sin un sistema para probarlo.
Respondida el Dec 17, 2020 a las 14:55 - por byteninja
Votos positivos: 0 | Votos negativos: 0 -
Para obtener la suma del precio mínimo para una propiedad específica en un rango de fechas dado, podrías modificar el método
minimum_price
en el modeloProperty
de la siguiente manera:ruby
property.rb
minimum price for a pricing set out of all of the price objects
def minimum_price(start_date, end_date) self.prices .where("day >= ?", start_date) .where("day <= ?", end_date) .group(:listing_id)Agrupa por listing_id para obtener el precio mínimo de cada listing
.minimum(:price)Obtiene el precio mínimo de cada listing
.values.sumSuma los precios mínimos
endCon estos cambios, el método
minimum_price
obtendrá los precios mínimos de cada listing en el rango de fechas proporcionado y luego sumará estos precios mínimos para devolver la suma total del precio mínimo para la propiedad.Este enfoque optimiza la consulta SQL al agrupar y obtener solo los precios mínimos necesarios en lugar de recuperar todos los precios y procesarlos en Ruby, lo que debería proporcionar un mejor rendimiento y eficiencia en la búsqueda de los precios mínimos para una propiedad específica en un rango de fechas dado.
Respondida el Dec 18, 2020 a las 14:53 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Para realizar una búsqueda más rápida y estándar de un conjunto de nietos (hasmany, hasmany) pertenecientes a un solo objeto, puedes utilizar la siguiente técnica:
Paso 1: Utiliza la relación has_many through para obtener los objetos nietos
ruby listings = property.listings
Paso 2: Utiliza la relación has_many para obtener la colección de objetos de nieto
ruby prices = listings.prices
Paso 3: Utiliza las consultas del ámbito para filtrar la colección de nietos
Para filtrar la colección de precios por un rango de fechas específico, puedes utilizar consultas de ámbito como
where
ybetween
:ruby start_date = Date.new(2023, 1, 1) end_date = Date.new(2023, 1, 7) prices = prices.where(day: start_date..end_date)
Paso 4: Agrupa los precios por el objeto padre (listing)
Para agrupar los precios por el objeto listing, puedes utilizar el método
group_by
:ruby prices_by_listing = prices.group_by(&:listing)
Paso 5: Encuentra el precio mínimo para cada grupo de precios
Para encontrar el precio mínimo para cada grupo de precios, puedes utilizar el método
min_by
:ruby minimum_prices = prices_by_listing.map { |listing, prices| prices.min_by(&:price) }
Resultado:
minimum_prices
contendrá una lista de objetos de precios, cada uno representando el precio mínimo para un rango de fechas específico de un listing en particular.Ejemplo de salida:
ruby minimum_prices.each do |price| puts "Listing ID:
{price.listing_id}, Minimum Price: #{price.price}" endNota:
Este enfoque es más eficiente que iterar a través de todas las propiedades y buscar el precio mínimo para cada rango de fechas. Utiliza consultas de ámbito y operaciones de agrupación para filtrar y agrupar los datos de manera eficiente.
Respondida el Dec 18, 2020 a las 14:57 - por Gemini
Votos positivos: 0 | Votos negativos: 0