2014-10-28 3 views
0

У меня есть некоторые модели Rails, которые выглядят немного как это:ActiveRecord: Используя среднее значение соответствующей модели в запросе

class Manufacturer 
    has_many :widgets 
end 

class Widget 
    belongs_to :manufacturer 
    has_many :listings 

    def weighted_average 
    listings.sum('value * stock')/listings.sum('stock') 
    end 
end 

class Listing 
    # Represents that a merchant is selling some widgets 
    belongs_to :widget 
    belongs_to :merchant 
    # Model has a :price, eg. $5.99 
    # Also has a :stock, eg. 45 units 
end 

Теперь я хочу, чтобы найти все Listing объекты, где Listing#value ниже weighted_average из Widget принадлежит.

Например, если конкретный виджет имеет среднюю цену в размере 5 долларов США, и есть списки за 4, 4 и 4 доллара США, я бы хотел вернуть первые два - так как они ниже средней цены и представляют собой хорошая сделка.

В запросе должен быть указан список всех недорогих объявлений для всех виджетов, и я хотел бы иметь возможность сделать это в одном запросе.

Как это сделать с помощью запросов ActiveRecord? В идеальном псевдокоде, это было бы что-то вроде:

Listing.where('listing.price < widget.weighted_average') 
# Not possible, because weighted_average isn't a column in the DB, but a method. 
+0

Вы пытались: 'Listing.where ('price Alireza

+0

Что такое 'widgets.sum ('value * stock')/widgets.sum ('stock')' или, точнее, что такое 'widgets' здесь в методе weighted_average? – Surya

+0

Я хочу, чтобы это работало для нескольких виджетов, а не только для отдельных виджета. В приведенном выше предположении будет использоваться то же значение для предложения 'where', а не в среднем виджета листинга. Я также понял, что имел в виду 'listings.sum', а не' widgets.sum' - я отредактировал свой вопрос. –

ответ

0

Try:

Listing.joins(:widget).where("#{Listing.table_name}.price < ?", 15) 

Edit:

Номер должен быть заменен на средневзвешенное результат функции. В зависимости от используемой базы данных это может быть один запрос sql, который возвращает именно то, что вы хотите. Например, для PostgreSQL HAVING требуется условие.

+0

Я обновил свой вопрос, чтобы быть немного яснее - запрос должен содержать список всех недорогих объявлений для всех виджетов, и я хотел бы иметь возможность сделать это в одном запросе. Число динамическое и нуждается в поиске в запросе, а не в переменной. –

+0

Посмотрите на предложение 'HAVING'. – blelump

Смежные вопросы