Giving a model attributes methods
My Song
model has a lyrics
text attribute. Since new lines are \n
-separated in my lyrics, I often find myself doing this in my views to make the lyrics HTML-friendly:
@song.lyrics.strip.gsub(/\n/, "\n<br />")
I'm repeating the gsub
logic all over my application, and, worse still, I can't change the format in which I store my lyrics without touching everywhere I tried printing them as HTML.
I'd like to abstract this so that I can write this in my views:
@s开发者_Python百科ong.lyrics.to_html
So that the strip.gsub(/\n/, "\n<br />")
logic is present in only one place in my application (in the to_html
method).
What's the best way to do this?
If you need to use the exact @song.lyrics.to_html
syntax and you don't want to create a Lyrics model, you can add a singleton method to the string returned by the lyrics
method:
class Song
def lyrics
str = read_attribute(:lyrics)
def str.to_html
strip.gsub(/\n/, "\n<br />")
end
str
end
end
However, this is not really a great design. For something more re-usable you might want to write a module with a to_html
method like this:
module HtmlFormatter
def to_html(attribute)
send(attribute).strip.gsub(/\n/, "\n<br />")
end
end
If you include HtmlFormatter
in your Song model you can call the method like this:
@song.to_html(:lyrics)
So it doesn't follow your desired syntax exactly, but I think it's a better design.
You might also want to consider a separate Lyrics model which could have all kinds of features, but this might be too heavy for your application.
Since is a view-related issue, you can place your to_html method on the ApplicationHelper module
module ApplicationHelper
def to_html(str)
str.strip.gsub(/\n/, "\n<br />")
end
end
so, on your views :
<% = to_html(@song.lyrics) %>
精彩评论