Либо .each делать, либо .Все не работает, как я думаю, это должно - PullRequest
2 голосов
/ 01 апреля 2012

Поэтому, когда кто-то оценивает магазин, я хочу, чтобы модель магазина рассчитывала его новый средний рейтинг и сохранял его в базе данных (вместо того, чтобы вычислять средний каждый раз, когда кто-то смотрит на него). Поэтому я написал следующий фрагмент кода, и он не работает.

Цикл всегда повторяется ровно один раз, независимо от того, сколько существует shop_ratings в базе данных с идентификатором магазина в качестве shop_id. Я немного поэкспериментировал с этим и обнаружил, что каждый раз, когда передается новый рейтинг, функция вызывается успешно, но она запускает цикл только один раз и устанавливает среднее значение для первого рейтинга.

Я не знаю, является ли "запрос", который устанавливает переменную оценок, неправильным или неправильным является цикл.

class Shop < ActiveRecord::Base
  has_many :shop_ratings

  attr_accessible :name, :latitude, :longitude

  validates_presence_of :name
  validates_presence_of :latitude
  validates_presence_of :longitude

  def distance_to(lat, long)
    return (self.longitude - long) + (self.latitude - lat)
  end

  def find_average

    total = 0
    count = 0
    ratings = ShopRating.all(:conditions => {:shop_id => id})
    ratings.each do |submission|
      total = total +  submission.rating
      count = count + 1
    end
    update_attribute :average_rating, total/count
  end      

end

Ответы [ 2 ]

2 голосов
/ 01 апреля 2012

Вот лучший метод find_average (кстати, он должен называться set_average_rating, потому что вы его не находите, вы его сохраняете)

shop.rb - Замена для: find_average

def set_average_rating
  update_attribute(:average_rating, shop_ratings.average(:rating))
end      

Как видите, мы используем метод вычисления среднего AR, который возвращает число с плавающей запятой. Док: http://ar.rubyonrails.org/classes/ActiveRecord/Calculations/ClassMethods.html#M000293

Говоря о числах с плавающей точкой, причина того, что ваш существующий код кажется не правильно вычисляет среднее значение, вероятно, потому что вы не говорите ruby, что окончательное среднее значение должно быть числом с плавающей точкой, а не целым числом. Надеемся, что вы определили поле вашего магазина # average_rating как число с плавающей запятой или десятичное число, а не как целое число.

0 голосов
/ 01 апреля 2012

если вы хотите знать, что происходит, вставьте в код некоторую отладочную информацию:

    ratings = ShopRating.all(:conditions => {:shop_id => id})
    # add this log
    Rails.logger.info "==== the raings of this Shop: #{ratings.inspect}"
    ratings.each do |submission|

и, вероятно, вы увидите, что рейтинги содержат только 1 элемент.

, поэтому я предлагаюВы повторно внедрили свой код:

измените:

# previous: 
ratings = ShopRating.all(:conditions => {:shop_id => id})  
ratings.each do |submission|

на:

# because you already defined  :
# has_many :shop_ratings
shop_ratings.each do |submission|
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...