views:

71

answers:

6

controller

@articles = current_user.articles

view

<% @articles.each do |article| %>
  <%= 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?

+2  A: 

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.

Cimm
+2  A: 

There are the try method for that

<% @articles.each do |article| %>
  <%= link_to "#{article.title} , #{article.author.try(:name)}" articles_path%>
<% end %>
shingara
Cool, didn't know about the try method. This solution will print the comma even when it's not needed though...
Cimm
@shingara, cool +1 for the try method http://api.rubyonrails.org/classes/Object.html#M000293
Salil
+1  A: 

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
Steve Weet
+1  A: 

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) %>
Slobodan Kovacevic
Those two link_to lines are almost identical. It hurts my eyes.
nathanvda
+4  A: 

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 %>
Simone Carletti
+2  A: 

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.

vise