Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 body_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.

like image 897
isthmus Avatar asked Jun 07 '11 17:06

isthmus


2 Answers

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 returns unless you actually need them. The result of the last statement in a method is implicitly the value returned from the method.

like image 169
meagar Avatar answered Nov 12 '22 16:11

meagar


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.

like image 20
pdobb Avatar answered Nov 12 '22 16:11

pdobb