有没有办法像html_safe一样定义模型的属性?

时间:2011-06-07 17:29:39

标签: ruby-on-rails ruby-on-rails-3 xss

我有一个名为Feature的模型,其中包含一个名为body_string的变量,其中包含我要呈现的HTML标记,而不是转义。

每次我在观看中引用body_string时,我都需要使用<%=raw.html_safe。这似乎是多余的,而不是那么干。

有没有办法让body_string变量一劳永逸地建立为html_safe

我假设这会发生在app/models/feature.rb文件中,但我无法弄清楚正确的语法是什么。我想到了这个:

def body_string
  return self.body_string.html_safe
end

但是Rails并不喜欢它;它引发stack level too deep例外。

当然,我可以使用不同的名称定义变量/方法:

def safe_body_string
  return self.body_string.html_safe
end

然后只需将视图中的所有引用从body_string更改为safe_body_string。但不知何故,这似乎与第一次使用raw.html_safe一样干涸。

有关如何最好地处理此问题的任何见解?我觉得必须有一些非常优雅的东西,我只是没有看到。

4 个答案:

答案 0 :(得分:9)

只需使用read_attribute即可避免对body_string的递归调用:

def body_string
  read_attribute(:body_string).html_safe
end

read_attributewrite_attribute补充,用于在模型中设置属性。

关于风格的说明:除非您确实需要,否则不要使用明确的return。方法中最后一个语句的结果隐式地是从方法返回的值。

答案 1 :(得分:1)

虽然@meager的答案肯定会有效,但我并不认为这个逻辑属于模型。仅仅因为它为模型层添加了视图级别的关注点(HTML安全性),它应该只包含业务逻辑。相反,我建议使用Presenter(请参阅http://nithinbekal.com/posts/rails-presenters/或为此找到一个宝石 - 我个人喜欢Display Case)。您的演示者可以轻松覆盖body_string方法,并在视图中显示时提供.html_safe指定。通过这种方式,您可以分离您的疑虑,并可以继续从其他模型中获取body_string,而不会混淆视图问题。

答案 2 :(得分:0)

也许这个宝石对你有用。当内容完全可信时,我也想停止重复html_safe。

http://rubygems.org/gems/html_safe_attribute

答案 3 :(得分:0)

或者你也可以使用这种方法,

def body_string
  super && super.html_safe
end