查询中的虚拟属性

时间:2011-08-03 12:01:59

标签: ruby-on-rails activerecord

用户模型具有 all_scores 属性,我创建了以下方法

models / user.rb

def score
  ActiveSupport::JSON.decode(self.all_scores)["local"]
end

我正在尝试使用此虚拟属性分数来过滤用户。例如: 我需要得分超过50的用户。问题是我不能将虚拟属性用作查询中的常规属性。

User.where("score > 50") # i can't do this.

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

嗯,“最简单”的解决方案可能是User.all.select{|user| user.score > 50}。显然这是非常低效的,将每个用户记录从数据库中拉出来。

如果您想进行涉及得分的查询,为什么不在用户表中添加score列?只要all_scores发生更改,您就可以更新它。

class User < AR::Base
  before_save :set_score, :if => :all_scores_changed?

  protected
  def set_score
    self.score = ActiveSupport::JSON.decode(self.all_scores)["local"] rescue nil
  end
end

这也可以避免在您访问user#score时不断反序列化JSON数据。