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

时间:2015-03-19 17:46:33

标签: ruby-on-rails ruby beforeupdate

在我的应用中,我有note.rb,其架构如下所示。我想要做的是限制编辑笔记的能力。基本上,如果在过去24小时内创建了笔记,则可以更新所需内容。 24小时后,您所能做的就是更改remind_at时间。我在note.rb文件中有一个方法可以检查注释是否可编辑。如果是我显示不同的部分。但是这只限制了前端,如果有人将编辑窗口打开,或者输入了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

2 个答案:

答案 0 :(得分:1)

我不明白,该模型不应该查看params [:reschedule]来了解它是否只是改变了remind_at时间" - 模型是被更改的东西,它应该能够查看实际被更改的内容并确保它只是remind_at

即使您可以轻松地查看params[:reschedule]也是不对的 - 可以想象params[:reschedule]可以在修改其他属性的同时设置,并且您不会&# 39;我想也允许这样做。在模型中执行此操作的唯一一点是 not 以信任控制器正在做正确的事情(并且没有安全漏洞),但要确保只有实际允许的内容才能完成。

如果我理解正确,那么,如果remind_at过了一段时间,那么允许的内容除了created_at之外不会更改任何属性。

那么您真正需要做的只是查看验证钩子中哪些属性发生了变化?

我相信changed方法应该可以做到这一点。它返回自上次保存以来已更改的属性列表。如果帖子太旧,您需要确保它们只包括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

答案 1 :(得分:0)

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