开发者

need an empty string, but getting an exception in ruby on rails

开发者 https://www.devze.com 2023-01-01 11:07 出处:网络
controller @articles = current_user.articles view <% @articles.each do |article| %> <%=开发者_Go百科 link_to \"#{article.title} , #{article.author.name}\" articles_path%>

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 %>
0

精彩评论

暂无评论...
验证码 换一张
取 消