防止在Rails模型中更改一个字段

时间:2013-02-08 19:23:54

标签: ruby-on-rails-3 validation hobo

我有两个相关模型 - 比方说ActivityStepActivity has_many :stepsStep belongs_to :activity表示steps的表格有activity_id列。

这是在Hobo 1.3中,所以Rails 3.0。

我想要的是确保在Step创建之后无法将某个步骤移动到另一个Activity。我们不希望activity_id字段发生变化。

我已从编辑表单中删除了该字段,但我正在寻找更强的约束。基本上我想在update(不在create)上验证该列未被触及。 Hobo的文档没有提出Hobo中的任何类型,所以我正在查看Rails validations,但到目前为止,我还没有找到我记得的“仅在更新时做这个”约束,也没有验证事情没有改变。

3 个答案:

答案 0 :(得分:34)

您可以使用attr_readonly :your_field_name将属性声明为read_only。 但是,如果您尝试编写此属性,则不会创建错误,它将无提示失败。 (对于所有SQL更新,将忽略此属性)

另一种选择可能是,为此案例编写验证,可能如下所示:

class Step < ActiveRecord::Base
  validate :activity_id_not_changed

  private

  def activity_id_not_changed
    if activity_id_changed? && self.persisted?
      errors.add(:activity_id, "Change of activity_id not allowed!")
    end
  end
end

persisted?如果不是新记录则返回true,并且不会被销毁。

链接:

http://api.rubyonrails.org/classes/ActiveRecord/ReadonlyAttributes/ClassMethods.html#method-i-readonly_attributes

http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-persisted-3F

答案 1 :(得分:1)

我认为您也可以使用Hobo权限系统执行此操作:http://hobocentral.net/manual/permissions

例如:

def update_permitted?
  acting_user.administrator && !activity_id_changed?
end

答案 2 :(得分:1)

通过验证是否包含:

  validates :activity_id,
            inclusion: { in: ->(i) { [i.activity_id_was] } },
            on: :update

不需要其他方法。