Как я могу вычислить условную сумму в моей модели? - PullRequest
2 голосов
/ 23 сентября 2010

Скажите, что я хочу что-то как это в Rails:

class Proposal < ActiveRecord::Base
    def interest_level
        self.yes_votes.count - self.no_votes.count
    end

  private
    def yes_votes
        self.votes.where(:vote => true)
    end

    def no_votes
        self.votes.where(:vote => false)
    end
end
  1. Что я в основном сделал неправильно в приведенном выше коде?(Я понимаю, что это, вероятно, ужасно во многих отношениях.)
  2. Какой правильный способ сделать это с точки зрения Rails?
  3. Какие соображения я должен помнить с точки зрения базы данных?(Например, даже если код, подобный приведенному выше , был бы возможным, я предполагаю, что он будет чрезмерным на стороне БД. Но, естественно, я не совсем уверен.)

Ответы [ 3 ]

2 голосов
/ 23 сентября 2010

Учитывая загрузку базы данных, я рекомендую реализовать собственный счетчик кэша.Я хотел бы сделать так:

class Vote < ActiveRecord::Base

    def after_create
      self.update_counter_cache
    end

    def after_destroy
      self.update_counter_cache
    end

    def update_counter_cache
      self.proposal.yes_votes_count = self.proposal.votes.where(:vote=>true)
      self.proposal.no_votes_count = self.proposal.votes.where(:vote=>false)
      self.propsal.save
    end
end

Обратите внимание, вы должны добавить две колонки к вашей Proposal модели.

add_columns_migration.rb

add_column :proposals, :yes_votes_count, :integer
add_column :proposals, :no_votes_count, :integer
2 голосов
/ 23 сентября 2010

предложение класса

def interest_level
    self.votes.sum('votes', :conditions => {:votes = true}) - self.votes.sum('votes', :conditions => {:votes = false})
end

end

спасибо, Anubhaw

1 голос
/ 23 сентября 2010

Я действительно не вижу ничего плохого в вашем коде. Хотя есть несколько способов выполнить то, что вы, похоже, пытаетесь сделать, ваш метод, похоже, должен работать нормально (хотя у меня ограниченный опыт работы с Arel).

Другим способом решения этой проблемы может быть простое изменение метода interest_level:

def interest_level
    self.votes.count - self.no_votes.count * 2  # same as (total - no_votes) - no_votes
end

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

...