24

我有两个相关的模型 - 比如说ActivityStep。这意味着表Activity has_many :steps有一个列。Step belongs_to :activitystepsactivity_id

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

我想要的是确保Step创建后无法将步骤移至另一个Activity. 我们不希望该activity_id领域发生变化。

我已经从编辑表单中删除了该字段,但我正在寻找更强大的约束。本质上,我想验证update(而不是create)该列没有被触及。Hobo 的文档并没有在 Hobo 中提出任何类似的建议,所以我正在查看Rails 验证,但到目前为止,我还没有找到我记得的“仅在更新时执行此操作”约束,也没有验证某些东西不是' t 变化。

4

3 回答 3

54

您可以使用 将属性声明为 read_only attr_readonly :your_field_name。但是,如果您尝试编写此属性,这不会产生错误,它会静默失败。(所有 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

于 2013-02-08T20:53:53.330 回答
16

验证包含:

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

不需要额外的方法。

于 2019-04-24T08:26:26.000 回答
1

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

例如:

def update_permitted?
  acting_user.administrator && !activity_id_changed?
end
于 2013-02-09T16:36:56.880 回答