2013-04-15 61 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

相關問題