2014-09-19 42 views
-1

我想讓用戶只有在report.published = false的情況下編輯字段report.plan。如果report.published = true他們試圖保存更改,我想拋出一個錯誤。基於Rails中布爾值的數據庫列鎖定值

我已經寫了下面的代碼來做到這一點:

class Report < ActiveRecord::Base 
    validate :cannot_update_plan_after_published, on: :publish_plan! 

    def publish_plan!(plan) 
    self.plan = plan 
    self.published = true 
    self.save 
    end 

    private 

    def cannot_update_plan_after_published 
     if self.published? 
     errors.add(:plan, "You cannot change the plan once it has been published.") 
     end 
    end 
end 

但是,這是行不通的。當我在已發佈的報告上致電publish_plan!時,它會進行保存。例如:

> f = Report.last 
=> #<Report id: 12, plan: "a", published: false> 
> f.publish_plan!("b") 
    (0.1ms) begin transaction 
    (0.4ms) UPDATE "reports" SET "plan" = 'b', "updated_at" = '2014-09-18 18:43:47.459983' WHERE "reports"."id" = 12 
    (9.2ms) commit transaction 
=> true 
> f = Report.last 
    Report Load (0.2ms) SELECT "reports".* FROM "reports" ORDER BY "reports"."id" DESC LIMIT 1 
=> #<Report id: 12, plan: "b", published: true> 
> f.publish_plan!("c") 
    (0.1ms) begin transaction 
    (0.4ms) UPDATE "reports" SET "plan" = 'c', "updated_at" = '2014-09-18 18:43:53.996191' WHERE "reports"."id" = 12 
    (8.7ms) commit transaction 
=> true 
> Report.last 
    Report Load (0.2ms) SELECT "reports".* FROM "reports" ORDER BY "reports"."id" DESC LIMIT 1 
=> #<Report id: 12, plan: "c", published: true> 

我如何得到這個領域成爲不可編輯一次report.published = true

回答

2

嘗試刪除on: :public_plan!。這樣,驗證應該在每次保存模型時運行。

validate :cannot_update_plan_after_published 

在這裏看到更多的細節:Adding a validation error with a before_save callback or custom validator?

此外,對於驗證方法本身,它更改爲以下:

def cannot_update_plan_after_published 
    if self.published? && self.published_changed? == false 
    errors.add(:plan, "You cannot change the plan once it has been published.") 
    end 
end 

這使您可以將其設置在第一時間發佈計劃。

+0

你說得對,謝謝 – 2014-09-19 16:15:50