我是一个Post belongs_to :user
我要保留已删除用户帖子的应用程序。在查看作者被删除的帖子时,这可能会导致视图出错。我试着这样做:
class Post < ActiveRecord::Base
belongs_to :author, class_name: 'User', foreign_key: 'user_id'
def author
author || NullUser.new
super
end
end
这会导致“堆栈级别变深”错误。为什么?我能做到这一点:
class Post < ActiveRecord::Base
belongs_to :user
def author
user || NullUser.new
end
def author=(user)
self.user = user
end
end
但以这种方式混淆我的协会似乎并不正确。什么是最好的方法呢?
答案 0 :(得分:13)
要回答你的问题,
1. def author
2. author || NullUser.new
3. super
4. end
在第1行中,您正在定义author
方法。然后在第2行,你再次调用那个作者方法!这种情况一直在发生,并且你得到的堆栈级别太深了。正确的方法是,
def author
super || NullUser.new
end
所以你不再在内部调用author方法了。你只是调用超类或返回NullUser。如果您在调用super
时收到nil错误,请添加额外的nil检查:
def author
(super || NullUser.new) rescue NullUser.new
end
救援声明将捕获所有错误,然后返回NullUser.new,因此您不必担心超级抛出错误。
编辑:
处理看起来更好的超级抛出异常的另一种方法:
def author
(super rescue nil) || NullUser.new
end
答案 1 :(得分:3)
如果您想保留已删除用户的帖子,最好不要真正“删除”它们。
另一种选择是“软删除”。只需添加一个布尔列,说“已删除”或“无效”。
因此,当您要删除用户时,请检查他是否有帖子。如果没有,硬删除他。如果有,软删除。
这样事情就会变得简单和干净。
另一种方法是“窃取”帖子。删除用户时,请在特殊用户帐户下移动所有帖子,然后将其删除。
无论哪种方式,你都不会破坏这种关联。