2017-09-28 55 views
0

我有一個名爲「Scores」的表,它有4列「first」,「second」,「third」和「average」保持用戶的得分記錄。如何將一條記錄中的多列的計算結果更新到帶有rails的postgresql數據庫中

當用戶最初創建記錄時,他可以將「平均」列留空。然後他可以稍後編輯所有3個分數。

編輯之後,用戶可以在他的節目頁面中看到計算的平均(或求和,或任何計算結果),因爲我有

高清顯示 @ave =(@ score.first + @score .second + @ score.third)/ 3 end

但是,@ave不在數據庫中,我如何將@ave更新到我的數據庫的「平均」列中?

  1. 理想情況下,如果計算髮生在更新到數據庫之前,最好是所有4個值都可以一起更新到數據庫中。它可能與Active Record Callbacks有關,但我不知道該怎麼做。

  2. 第二種方法,我想我需要在數據庫中使用「觸發器」,以便在其他3列更新後立即計算和更新「平均」列。如果這是你怎麼做的,請讓我知道和比較解決方案編號1的優勢。

  3. 最後的方法,因爲用戶已經知道他的顯示頁面的平均值,我不必更新立即將平均值計算爲「平均值」列。我想我可以將此留給late_job或後臺工作。如果你是這樣做的,請讓我知道如何。

預先感謝您!(紅寶石2.3,導軌5.0.1,PostgreSQL的9.5

回答

1

除非你真的需要存儲在數據庫中由於某種原因,平均而言,我想補充一個歸因於分數模型:

def average 
    (first + second + third)/3.0 
end 

如果一個或多個可能不存在,我想:

def average 
    actual_scores = [first, second, third].compact 
    return nil if actual_scores.empty? 
    actual_scores.sum/actual_scores.size 
end 

如果您確實需要保存的平均水平,那麼我想補充一個before_validate回調:

before_validation do 
    self.average = (first + second + third)/3.0 
end 
+0

我用before_save代替。感謝您的幫助! – Denny

0

思路1和2是完全有效的方法。思想3是矯枉過正,我會強烈反對這種做法。

在想法1中,您只需查看每個單獨的值(不包括平均值)並生成包含在插入語句中的平均值就可以了。

想法2需要製作三gger如下:

CREATE OR REPLACE FUNCTION update_average() 
    RETURNS trigger AS 
$BODY$ 
BEGIN 
    NEW.AVERAGE=(NEW.first+NEW.second+NEW.third)/3; 
    RETURN NEW; 
END; 
$BODY$ 

然後將其指定你的桌子上的更新或插入運行:

CREATE TRIGGER last_name_changes 
    BEFORE INSERT or UPDATE 
    ON scores 
    FOR EACH ROW 
    EXECUTE PROCEDURE update_average(); 
+0

我很抱歉,我只能做一個答案正確的答案!你已經證明數據庫觸發器方法也可以。非常感謝! – Denny

相關問題