controller
@articles = current_user.articles
view
<% @articles.each do |article| %>
<%=开发者_Go百科 link_to "#{article.title} , #{article.author.name}" articles_path%>
<% end %>
Sometimes the article has no author, so is null in the database, which results in the following error
You have a nil object when you didn't expect it! The error occurred while evaluating nil.name
I still want to output the article title in this scenario, whats the best way to do this please?
Add a new instance method to your Article
model.
class Article
def title_and_author
returning "" do |s|
s << title
s << ", " << author.name if author.name?
end
end
end
then in your view
<% @articles.each do |article| %>
<%= link_to article.title_and_author, articles_path %>
<% end %>
I suppose you could do something like this:
<% @articles.each do |article| %>
<%= link_to (article.author ? "#{article.title} , #{article.author.name}" : article.title), articles_path %>
<% end %>
Using the short if/else form. If the author exist print the title and author, if not, print only the title.
There are the try
method for that
<% @articles.each do |article| %>
<%= link_to "#{article.title} , #{article.author.try(:name)}" articles_path%>
<% end %>
Yet another solution:
<% @articles.each do |article| %>
<%= link_to [article.title, article.author.try(:name)].reject{ |obj| obj.nil? }.join(', ') articles_path %>
<% end %>
You should probably have a helper if you find it too dirty.
If you are likely to come across this issue in a number of places within your application you may wish to modify the model class by adding one of the following methods
Modify the name attribute to return blank rather than nil
def name
d = read_attribute(:name)
d.nil? ? " " : d
end
Insert a blank instead of a null to the database
def before_save
self.name = " " if self.name.nil?
end
Alternatively you could create a helper method that builds the link text based upon the existence of the name or not, like so
def link_text(title, name)
if name.blank?
title
else
"#{title} , #{name}"
end
I would go with creating a helper that wraps around link_to. Something like:
def link_to_article(article)
if article.author.nil?
link_to "#{article.title}", article_path(article)
else
link_to "#{article.title} , #{article.author.name}" article_path(path)
end
end
# and in view simply do:
<%= link_to_article(article) %>
A 2020 solution using safe navigation could probably look something like this:
<%= link_to [article&.title, article&.author&.name].compact.join(",") articles_path %>
精彩评论