Is there any way to define a model's attribute as always html_safe?
I have a model called Feature
with a variable called body_string
, which contains HTML markup I'd like to render, rather than escape.
Every time I reference body_string
in my views, I need to use <%=raw
or .html_safe
. This seems redundant and not-so-DRY.
Is there any way that I can establish once-and-for-all the body_string
variable as html_safe
?
I'm assuming this would happen in the app/models/feature.rb
file, but I can't figure out what the right syntax would be, exactly. I've thought of this:
def bod开发者_如何转开发y_string
return self.body_string.html_safe
end
But Rails doesn't like it; it raises a stack level too deep
exception.
Naturally I could define a variable/method with a different name:
def safe_body_string
return self.body_string.html_safe
end
And then just change all references in the views from body_string
to safe_body_string
. But somehow this seems almost as un-DRY as simply using raw
or .html_safe
in the first place.
Any insights to how best to handle this? I feel like there must be something really elegant that I'm just not seeing.
Just use read_attribute
to avoid the recursive call to body_string
:
def body_string
read_attribute(:body_string).html_safe
end
read_attribute
is complemented by write_attribute
for setting attributes from within your model.
A note on style: Don't use explicit return
s unless you actually need them. The result of the last statement in a method is implicitly the value returned from the method.
While @meager's answer will definitely work, I don't think this logic belongs in a model. Simply because it adds view-level concerns (HTML safeness) to the model layer, which should just include business logic. Instead, I would recommend using a Presenter for this (see http://nithinbekal.com/posts/rails-presenters/ or find a gem for this -- I personally love Display Case). Your presenter can easily override the body_string
method and provide the .html_safe
designation when displaying in the view. This way you separate your concerns and can continue to get body_string
from other models without mixing in the view concern.
Maybe this gem is useful for you. I also wanted to stop repeating html_safe all the time when the content is completely trustable.
http://rubygems.org/gems/html_safe_attribute
Or you can also use this approach,
def body_string
super && super.html_safe
end
精彩评论