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
在我的应用程序中,我有 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