Почему мой столбец базы данных rank_sum все еще равен нулю? - PullRequest
0 голосов
/ 20 марта 2011

Итак, у меня есть эти два метода в моей модели видео. Первый из них принимает параметр store и делает с ним несколько математических операций, возвращая rounded_num. Второй метод должен установить rank_sum в базе данных на значение rounded_num, передав значение vote_sum методу rank_sum. Вот методы:

def rank_sum(score)
  order = Math.log10(([score.abs,1].max))

  if score > 0
    sign = 1
  elsif score < 0
    sign = -1
  else
    sign = 0
  end

  seconds = self.created_at - DateTime.new(1970,1,1)
  long_num = order + sign * seconds / 45000
  return rounded_num = (long_num * 10**7).round.to_f / (10**7)
end

def update_rank_sum
  new_rank = rank_sum(self.vote_sum)
  video.update_attributes!(:rank_sum => new_rank)
end

Однако rank_sum не устанавливается. Значение для rank_sum каждого видео по-прежнему равно нулю. Как мне это исправить?

1 Ответ

1 голос
/ 20 марта 2011

Поскольку ваш метод rank_sum не взаимодействует напрямую с экземпляром модели Video (например, одним конкретным видео), а вместо этого просто выполняет некоторые вычисления, я бы сделал его методом класса. Это также делает так, чтобы ваш метод не перезаписывал собственный метод rank_sum Active Record, который он создал на основе столбцов в вашей базе данных.

Изменив некоторые имена для большей наглядности и очистив оператор return в вашем первом методе, я бы попробовал что-то вроде этого:

class Video < ActiveRecord::Base
  before_update :update_rank_sum

  def self.calculate_rank_sum(score, created_at)
    order = Math.log10(([score.abs,1].max))

    if score > 0
      sign = 1
    elsif score < 0
      sign = -1
    else
      sign = 0
    end

    seconds = created_at - DateTime.new(1970,1,1)
    long_num = order + sign * seconds / 45000
    (long_num * 10**7).round.to_f / (10**7)
  end

  def update_rank_sum
    self.rank_sum = Video.calculate_rank_sum(self.vote_sum, self.created_at)
  end
end

Это будет пересчитывать столбец rank_sum при каждом сохранении записи. Если вы хотите пересчитать его только в случае изменения определенного поля, вы можете реализовать эту логику в обратном вызове update_rank_sum. Например, чтобы вычислить новый rank_sum, только если vote_sum был изменен:

def update_rank_sum
  if self.vote_sum_changed?
    self.rank_sum = Video.calculate_rank_sum(self.vote_sum, self.created_at)
  end
  true
end

Вы можете заменить vote_sum в vote_sum_changed? на любой столбец, который хотите проверить.

[Редактировать] Вам может потребоваться вернуть значение не false или nil в обратном вызове, чтобы убедиться, что запись все еще сохраняется (если вы возвращаете false из обратного вызова before_, это отменяет сохранение). Я обновил последний блок кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...