有没有`before_read`回调?

时间:2014-04-15 15:27:52

标签: ruby-on-rails

没有,但我想知道你将如何做以下事情。我试图拦截"如果设置了某些条件,则使用另一个属性覆盖它:

# pseudo code
class Post < ActiveRecord::Base
    before_read :intercept_attributes

    def intercept_attributes
       if self.is_soft_deleted?
         define_method content do
            "This message was deleted #{time_ago_in_words(self.soft_deleted_at)} ago"
         end
       end
    end

end

帖子具有以下属性:contentsoft_deleted_at

对于这篇文章:

normal_post = Post.first
=> #<Post id: 0, content: "I am a fine comment", soft_deleted_at: nil >

评论显示没问题:

normal_post.comment #=> "I am a find comment"

但对于这篇文章:

soft_deleted_post = Post.last
=> #<Post id: 1, content: "I am a naughty post", soft_deleted_at: Tue, 15 Apr 2014 16:24:09 +0100 >

我希望这种情况发生:

soft_deleted_post.comment #=> "This message was deleted about five minutes ago"

那我该怎么做呢?如果有一个before_read回调,这将有效,但我不想反对轨道。那我怎么能这样做呢?

请注意,这里的类方法不合适,因为我需要访问self关键字。 (self.soft_deleted_at)

2 个答案:

答案 0 :(得分:3)

您可以简单地覆盖content这样的方法

class Post < ActiveRecord::Base    
    def content
       if is_soft_deleted?
            "This message was deleted #{time_ago_in_words(self.soft_deleted_at)} ago"
       else 
            self[:content]
       end
    end   
end

如果您想要访问原始内容,可以将此方法重命名为display_content或与您的域语言最匹配的名称。

答案 1 :(得分:0)

我不认为在你的模特中这样做是一个很好的做法。你应该在帮助者中做到这一点,或者,如果你不像许多人那样喜欢这种方法,那么看看装饰者:

https://github.com/drapergem/draper

http://railscasts.com/episodes/286-draper