Rails如何让"已删除"的model对象不能被编辑(二)

来源:互联网 发布:英语社交网络 编辑:程序博客网 时间:2024/06/07 18:09

在第一篇中我们讨论了如何控制model的hook流.

但是其实其中还是有未考虑到的地方,比如在新建一个model对象的时候,会报错:

ActiveRecord::ActiveRecordError: can not update on a new record object

意思是你不能在一个新建对象上调用update方法!

对应的代码如下:

def was_deleted=(new_val)    unless self.was_deleted        update_column(:was_deleted,new_val)    endend

无疑在update和new时都会调用该方法,所以我们必须搞清楚到底是什么原因然后才能做出处理.恰好rails提供一个changed?方法,官方的解释为:

Returns true if any of the attributes have unsaved changes, false otherwise.

注意是unsaved changes!!!如果是新建那么changed?自然返回true,所以我们重构如下:

def was_deleted=(new_val)    unless self.was_deleted        if !changed?            update_column(:was_deleted,new_val)        else            #do something ...        end    endend

问题是在else中做点什么,如果啥都不做was_deleted属性不会更新的哦!

第一次尝试如下:

alias :"was_deleted=" :"org_was_deleted="def was_deleted=(new_val)    unless self.was_deleted        if !changed?            update_column(:was_deleted,new_val)        else            org_was_deleted=(new_val)        end    endend

看上去不错,但实际运行会报错,提示找不到org_was_deleted=方法,因为org_was_deleted=是was_deleted=的别名,所以实际就是找不到was_deleted=方法!?你可能会奇怪,如果没有这个方法为什么会调用自定义的方法呢???

其实很简单,该model类中的确没有对应的was_deleted=方法,该方法是ActiveRecord::Base类(或其超类)自动生成的,所以我们不用操心自己创建别名了,只要简单的调用super即可,最终的代码如下:

def was_deleted=(new_val)    unless self.was_deleted        if !changed?            update_column(:was_deleted,new_val)        else            super        end    endend
0 0