Dealing with nil in views (ie nil author in @post.author.name)
I want to show a post author's name; <% @post.author.name %>
works unless author is nil. So I either use unless @post.author.nil?
or add a author_name method that checks for nil as in <% @post.author_name %>
. The latter I try to avoid.
The problem is that I may need to add/remove words depending on whether there is a value or not. For instance, "Posted on 1/2/3 by " would be the content if I simply d开发者_JAVA技巧isplay nil. I need to remove the " by " if author is nil.
Null object pattern is one way to avoid this. In your class:
def author
super || build_author
end
This way you will get an empty author no matter what. However, since you don't actually want to have an empty object sometimes when you do expect nil
, you can use presenter of some kind.
class PostPresenter
def initialize(post)
@post = post
end
def post_author
(@post.author && @post.author.name) || 'Anonymous'
end
end
Another way is using try
, as in @post.author.try(:name)
, if you can get used to that.
You can use try
:
<%= @post.author.try(:name) %>
It will attempt to call the name
method on @post.author
if it is non-nil. Otherwise it will return nil, and no exception will be raised.
Answer to your second question: In principle there is nothing wrong with the following:
<% if @post.author %>
written by <%= @post.author.name %>
<% end %>
or
<%= "written by #{@post.author.name}" if @post.author %>
But if this is a recurring pattern, you might want to write a helper method for it.
# app/helpers/authors_helper.rb or app/helpers/people_helper.rb
class AuthorsHelper
def written_by(author)
"written by #{author.name}" if author
end
end
# in your views
<%= written_by(@post.author) %>
Write a method which accepts any variable and checks to see if it is nuil first, and if it is not displays it. Then you only have to write one method.
I found your question interesting as I have often come across similar situations, so I thought I'd try out making my first Rails plugin.
I'm afraid I haven't put in any tests yet but you can try it out http://github.com/reubenmallaby/acts_as_nothing (I'm using Ruby 1.9.1 so let me know if you get any problems in the comments or on Github!)
精彩评论