2013-07-26 21 views
-1

我有一個明星示範模型,包括total_starsaverage_stars列於郵政型號:如何強制一列只允許以這種方式編號:1,1.5,2,2.5等等?

create_table "posts", force: true do |t| 
    t.string "title" 
    t.text  "content" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    t.integer "user_id" 
    t.integer "average_stars", default: 0, null: false 
    t.integer "total_stars", default: 0, null: false 
    end 

高清calculate_total_stars 如果[發佈] .INCLUDE(starable.class) 自我? starable.update_column(:total_stars,starable.total_stars + self.number) 端端

DEF calculate_average_stars ,如果[郵政] .INCLUDE(starable.class) self.starable.update_column?(:average_stars,starable.total_stars/starable.stars.count) 端端

所以,現在的問題是,如果average_stars3.6最終結果只是3。我不太確定什麼樣的計算或近似適用於五星評級系統。但我希望按以下方式進行:1,1.5,2,2.5 ...

有關如何修改average_stars列以實現該結果的任何建議?

+2

您想存儲1.5,2.5,但該列被定義爲整數。首先更改average_stars列的數據類型 –

回答

2

而不是聲明你的平均列作爲一個整數聲明爲浮動(或十進制):

t.float "average_stars", default: 0, null: false 

然後,當你做你的計算做:

def calculate_average_stars 
    if [Post].include?(starable.class) 
    self.starable.update_column(:average_stars, starable.total_stars.to_f/starable.stars.count) 
    end 
end 

哪位能給你是一個十進制值而不是一個舍入/截斷的整數。 .to_f是那裏的重要部分。

如果它是圓形的或只有小數點固定數量或者使用在遷移十進制列(這需要一個:限制)或做一些mathy東西:

((starable.total_stars.to_f/starable.stars.count) * 100).round/100.0 
1
def calculate_average_stars 
    if starable.is_a?(Post) 
    exact_average = starable.total_stars.to_f/starable.stars.count 
    rounded_average = exact_average - (exact_average % 0.5) 
    starable.update_column(:average_stars, rounded_average) 
    end 
end 
+0

以小數爲單位進行修改非常聰明,但您偶爾會得到奇怪的浮點精度,它看起來像4.5000000000000002。我認爲最好是在一個「合理」的長度上進行回合和截斷。我無法確定提問者是否真的想讓它繞到最近的半星。如果他做的比你的答案(與浮柱相結合)更接近正確。只要做mod,然後確定它被截斷到正確的小數位(val * 10/10.0)。 – olamork

相關問題