2013-04-15 35 views
2

我有一个考试模型,它具有数据库属性score。现在,我想拥有另一个名为rating的属性,它将此分数转换为评分(A,B,C,D,F)。我不想为rating创建另一列,所以我用虚拟属性如下:为Rails对象创建临时属性并传递给View

class Exam < ActiveRecord::Base 
    attr_accessor :rating 
    after_initialize :set_rating 
    after_find :set_rating 

    private 
    def set_rating 
     self.rating = case score 
      when 0..49 then "F" 
      when 50..79 then "B" 
      else "A" 
    end 
end 

这工作,在这个意义上,我可以打电话

e = Exam.find_by_student("John") 
e.rating 

然而,对象e做没有附加属性评级。因此,如果我将对象e传递给Rails视图,则无法获得e.rating,其中rating是属性。

我该如何实现我想要的,即after_find可用的无数据库属性?

谢谢。

回答

7

废弃所有这些,只需定义一种名为rating的方法。

class Exam < ActiveRecord::Base 

    # ... 

    def rating 
    case score 
     when 0..49 then "F" 
     when 50..79 then "B" 
     else "A" 
    end 
    end 

end 

如果你需要在一个JSON响应这一“属性”,可以将:methods参数传递给as_json显式地包含它:

render json: @exam.as_json(members: :rating) 
+0

问题是,当我通过对象考试,'查看',我不再有这种方法'评级'可用。所以你的解决方案不适合我的情况。 – AdamNYC

+0

嗯。我可以保证你*有*方法,并且这个解决方案*将*适用于你的情况。您在课堂上定义的任何方法都将在视图中提供。你是否将方法定义为'private'?没有理由这样做,并且*会*使它看起来不会对“评级”做出响应。 – meagar

+1

我会创建一个新的RatingClass,保持模型清洁。 阅读更多在这里,与RatingExample:http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/ – Deradon

相关问题