在模型中使用回调来修改另一个模型的列(Rails)?

时间:2012-02-07 07:47:55

标签: ruby-on-rails

我有一个名为投票的模型,这就是 vote.rb 的样子:

class Vote < ActiveRecord::Base
  belongs_to :votable, :polymorphic => true
  belongs_to :user

  before_create :update_total

  protected

  def update_total
    self.total ||= 0
    self.total += self.polarity
  end
end

(它是多态的,因为它也属于另一个名为注释的模型。)

每次创建投票时,总计的值都会更新。例如,Vote.create(:polarity => 2)将生成:polarity => 2, :total => 2

我只是意识到这没有意义,因为:polarity总是等于:total。我真正想做的是让投票所属的模型total;在这种情况下发布评论投票属于帖子,发布有很多选票)以便每次都有投票已创建,帖子中的total列将会更新。像这样:

5月13日

Post.total = 3 (:id => 2)

Vote.polarity = 1 (:id => 1)
Vote.polarity = -1 (:id => 2)
Vote.polarity = 3 (:id => 3)

5月14日

Post.total = 4 (:id => 2)

Vote.polarity = 1 (:id => 1)
Vote.polarity = -1 (:id => 2)
Vote.polarity = 3 (:id => 3)
Vote.polarity = 1 (:id => 4)

1 个答案:

答案 0 :(得分:2)

您需要以这种方式更新可投票对象的总数:

def update_total
  if self.votable.class.column_names.include?("total")
    total_average = self.votable.total ||= 0
    self.votable.update_attribute(:total, total_average + self.polarity)
  end
end

或者你可以像@Sandip那样使用条件回调:

before_create :update_total, :if => defined_total

def defined_total
  self.votable.class.column_names.include?("total")
end

def update_total
  total_average = self.votable.total ||= 0
  self.votable.update_attribute(:total, total_average + self.polarity)
end