Могу ли я перенести этот расчет рельсов в базу данных? - PullRequest
3 голосов
/ 07 января 2012

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

Модели:

class Offer < ActiveRecord::Base
  has_many :lines
  has_many :items, :through => :lines
end

class Line < ActiveRecord::Base
  belongs_to :offer
  belongs_to :item
  # also has a 'quantity' attribute (integer)
end

class Item < ActiveRecord::Base
  has_many :lines
  has_many :offers, :through => :lines
  # also has a 'price' attribute (decimal)
end

Я хочу рассчитать цену предложения.В настоящее время у меня есть метод цен в классе «Предложение»:

def price
  self.lines.inject(0) do |total, line|
    total + line.quantity * line.item.price
  end
end

Я подозреваю, что вместо этого можно сделать расчет Offer.sum, который бы получал ответ непосредственно из БД, а не просматривал записино в разделе Вычисления в справочнике запросов ActiveRecord недостаточно подробностей, чтобы выручить меня.Кто-нибудь?

Спасибо!

Ответы [ 2 ]

3 голосов
/ 07 января 2012

Вы правы, что вы можете сделать это с sum. Примерно так:

class Offer < ActiveRecord::Base
  # ...

  def price
    self.lines.sum 'lines.quantity * items.price', :joins => :item
  end
end

Когда вы звоните, например, Offer.find( some_id ).price вышеприведенное построит запрос примерно так:

SELECT SUM( lines.quantity * items.price ) AS total
  FROM lines
  INNER JOIN items ON items.id = lines.item_id
  WHERE lines.offer_id = <some_id>
;
2 голосов
/ 07 января 2012

Иногда вам лучше с SQL.

SELECT SUM( lines.quantity * items.price ) AS total
  FROM offers
  INNER JOIN lines ON offers.id = lines.offer_id
  INNER JOIN items ON items.id = lines.item_id
  WHERE offers.id = 1
;
...