Rails如何让"已删除"的model对象不能被编辑(一)
2017-02-15 21:09
253 查看
这里的已删除被打了引号,意思是并未真的从数据库中删除,而是其有一个was_deleted属性,如果值为true则表示其已被删除.这时用户还能查看其内容,但无疑不能再编辑它了.
那么用rails的model验证和hook如何实现这样的效果呢?
首先编辑执行的是update方法,所以我们必须在before_update上下功夫:
首先想到的写法是:
但是这样的话将不可以把was_deleted属性设置为true!但这恰恰正是触发条件啊!
所以我们必须排除was_deleted属性被更新的情况:
貌似不错,但还有一个问题,因为你此时没有限制用户修改was_deleted属性,所以如果用户将一个已删除的model又改为未删除怎么办?即在was_deleted已经为true时将其设为false.
这取决于你怎么理解”已删除”这个功能.如果你认为可以将”已删除”的对象变为”未删除”,然后再操作之的话,那么这是可以接受的.
但这里我们不希望这样,当一个对象变为”已删除”后,就不可以做任何修改了!
所以我们还得写一个赋值钩子,以下是我的第一次尝试:
好吧,上面是一个死循环…
但你也不能这么写:
因为was_deleted后面没有一个真正的实例变量作为后备啊!
让我再想想…这样如何呢:
神马!还是死循环!看来update_attribute内部还是调用了赋值方法啊!
所以我们必须直接跳过赋值,直入数据库层了:
update_column跳过了验证,但是没关系.因为向数据库写入一个bool值无所谓成功或失败.
这样一番折腾后,我们达到了开头需要的效果 ;)
那么用rails的model验证和hook如何实现这样的效果呢?
首先编辑执行的是update方法,所以我们必须在before_update上下功夫:
before_update do |r| #do something end
首先想到的写法是:
before_update do |r| if r.was_deleted r.errors[:base] << "不可以编辑已删除的风险项!" false end end
但是这样的话将不可以把was_deleted属性设置为true!但这恰恰正是触发条件啊!
所以我们必须排除was_deleted属性被更新的情况:
before_update do |r| unless r.was_deleted_changed? if r.was_deleted r.errors[:base] << "不可以编辑已删除的风险项!" false end end end
貌似不错,但还有一个问题,因为你此时没有限制用户修改was_deleted属性,所以如果用户将一个已删除的model又改为未删除怎么办?即在was_deleted已经为true时将其设为false.
这取决于你怎么理解”已删除”这个功能.如果你认为可以将”已删除”的对象变为”未删除”,然后再操作之的话,那么这是可以接受的.
但这里我们不希望这样,当一个对象变为”已删除”后,就不可以做任何修改了!
所以我们还得写一个赋值钩子,以下是我的第一次尝试:
def was_deleted=(new_val) unless self.was_deleted self.was_deleted = new_val end end
好吧,上面是一个死循环…
但你也不能这么写:
def was_deleted=(new_val) unless self.was_deleted @was_deleted = new_val end end
因为was_deleted后面没有一个真正的实例变量作为后备啊!
让我再想想…这样如何呢:
def was_deleted=(new_val) unless self.was_deleted update_attributes(was_deleted:new_val) end end
神马!还是死循环!看来update_attribute内部还是调用了赋值方法啊!
所以我们必须直接跳过赋值,直入数据库层了:
def was_deleted=(new_val) unless self.was_deleted update_column(:was_deleted,new_val) end end
update_column跳过了验证,但是没关系.因为向数据库写入一个bool值无所谓成功或失败.
这样一番折腾后,我们达到了开头需要的效果 ;)
相关文章推荐
- Rails如何让"已删除"的model对象不能被编辑(二)
- Rails如何让"已删除"的model对象不能被编辑(三)
- Rails如何让"已删除"的model对象不能被编辑(一)
- Rails如何让"已删除"的model对象不能被编辑(二)
- Rails如何让"已删除"的model对象不能被编辑(三)
- [c#]Webservice中如何实现方法重载(overload)以及如何传送不能序列化的对象作参数
- [c#]Webservice中如何实现方法重载(overload)以及如何传送不能序列化的对象作参数
- GridView不能编辑更新或删除问题之一
- 如何在oracle存储过程中使用 create,drop 等不能"回滚" 的语句
- 如何在DataGrid控件中实现编辑、删除、分类以及分页操作
- 我的table有一备注型字段,我现在能在Dbrid中显示这字段,但是不能在Dbgrid上编辑,如何才能编辑该字段?
- sa帐号都不能查其它用户建的表吗?报没有对象错——如何解决?
- 如何在Web页面上直接打开、编辑、创建Office文档以及如何不能直接打开
- 如何利用GridView与UpdatePanel组合实现无刷新:新增、编辑、删除、分页效果?
- 我的table有一备注型字段,我现在能在Dbrid中显示这字段,但是不能在Dbgrid上编辑,如何才能编辑该字段?
- Webservice中如何实现方法重载(overload)以及如何传送不能序列化的对象作参数
- TTreeview如何保存自动删除的对象
- 如何在DataGrid控件中实现编辑、删除、分类以及分页操作
- 如何在DataGrid控件中实现编辑、删除、分类以及分页操作
- "automation服务器不能创建对象”的问题的解决方案总结大全