Rails 阻止更新模型中的某些值

Rails preventing update to certain values in a model

在我的应用程序中,我有 note.rb 架构如下所示。我想做的是限制编辑笔记的能力。基本上,如果笔记是在过去 24 小时内创建的,您就可以随意更新。 24 小时后,您所能做的就是更改 remind_at 时间。我在 note.rb 文件中有一个方法可以检查注释是否可编辑。如果是,我会显示不同的部分。但这仅限制前端,如果有人将编辑 window 打开,或输入 URL,他们仍然可以在 24 小时后编辑笔记。

我想做的是编写一个 before_update 方法来检查是否允许您更新笔记的 body。不管什么都可以更新remind_at时间。部分问题是控制器知道这是否只是对 remind_at 时间的更改的方式是通过 params[:reschedule]params 在模型中无法访问。

# == Schema Information
#
# Table name: notes
#
#  id                :integer          not null, primary key
#  body              :text
#  remind_at         :datetime
#  created_at        :datetime
#  updated_at        :datetime

# Only allow editing of notes that are less that 1 day old
  def editable?
    self.created_at > (Time.now-1.day)
  end

如果它的质量分配..然后在 attr_accessible 中包含该属性,或者在控制器或模型中明确设置它

我不明白,模型不应该看params[:reschedule]来知道它是不是"simply a change to the remind_at time"——模型是被改变的东西,它应该可以看在 实际更改的内容 并确保它只是 remind_at

查看 params[:reschedule] 是不对的,即使您可以轻松地做到这一点 — 可以想象 params[:reschedule] 可以在修改其他属性的同时设置,而您不会我也不想允许。在模型中这样做的唯一要点是 而不是 相信控制器正在做正确的事情(并且没有安全漏洞),但要确保只做实际允许的事情。

如果我理解正确的话,如果 created_at 超过特定时间,则允许更改任何属性但 remind_at

那么您真正需要做的只是查看验证挂钩中更改了哪些属性?

我相信 changed 方法应该可以做到这一点。它 return 自上次保存以来更改的属性列表。如果 post 太旧,您要确保它们只包含 remind_at

这有用吗?

 if self.created_at > (Time.now-1.day) &&
    self.changed.find {|k| k.to_s != "remind_at"}
         # BAD, they're trying to save some other attribute changed
 end

http://api.rubyonrails.org/classes/ActiveModel/Dirty.html#method-i-changed