从模型更新数据库中的列

时间:2016-06-26 09:42:15

标签: ruby-on-rails ruby ruby-on-rails-4

所以我有一个User模型和一个Post模型

Post属于用户

Post在数据库中有一个名为score

的字段

Post模型中,我有一个名为score的方法,根据字段为帖子提供分数(需要以这种方式完成):

def score
   score = 0

   if self.title.present?
     score += 5
   end
   if self.author.present?
     score += 5
   end
   if self.body.present?
     score += 5
   end

   score

end

问题:

Users个载荷和Posts载荷。所以我要做的是在得分后,我想将它保存到数据库中的每个score的帖子Post字段中。如果用户更新Post,则应更新分数。

我已经看过使用after_update :score!,但不明白如何应用逻辑

4 个答案:

答案 0 :(得分:2)

看起来有点像你正试图重新发明ActiveRecord为你提供的轮子。

如果您有一个数据库字段score,那么ActiveRecord会自动为attribute_reader提供attribute_writerscore,除非您真的真的,否则不应覆盖它们有充分理由,例如你需要在其中添加一些其他资源或一些严肃的业务逻辑。

使用before_save挂钩可以更方便地解决问题,该挂钩会在任何#create#update之前启动:

class Post
  attribute_accessible :score # if you have Rails 4.x you can omit this line

  before_save :update_score

  private
  def update_score
    new_score = 0
    self.score = [:title, :author, :body].each do |field|
      new_score += 5 if send(field).present?
    end

    self.score = new_score
  end

这样,ActiveRecord将为您处理保存,您的分数将始终保持最新状态。此外,Post#score将始终返回当前保存在数据库中的实际值

答案 1 :(得分:0)

你可以这样做 after_update :score!

def score!
   score = 0

   if self.title.present?
     score += 5
   end
   if self.author.present?
     score += 5
   end
   if self.body.present?
     score += 5
   end

   self.update_column(:score, score)

end

这将在您的Post模型中完成。

答案 2 :(得分:0)

您可以使用update_column方法执行此操作。像:

def score
   score = 0

   if self.title.present?
     score += 5
   end
   if self.author.present?
     score += 5
   end
   if self.body.present?
     score += 5
   end

   self.update_column(:score, score)

end

答案 3 :(得分:0)

您需要覆盖Post模型中的setter方法

attr_accessible :score

  def score=(value)
  score = 0
   if self.title.present?
     score += 5
   end
   if self.author.present?
     score += 5
   end
   if self.body.present?
     score += 5
   end 
    write_attribute(:score, score)
  end