基于Rails中的布尔值锁定数据库列的值

时间:2014-09-19 01:52:12

标签: ruby-on-rails ruby-on-rails-3 activerecord

我想让用户仅在report.plan时修改字段report.published = false。如果report.published = true他们试图保存更改,我想抛出一个错误。

我已经编写了以下代码来执行此操作:

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之后让此字段变为不可编辑?

1 个答案:

答案 0 :(得分: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

这允许您在第一次发布计划时进行设置。