Search code examples
ruby-on-railsrubymethodsconditional-statementsblogs

Next post breaks when going to the first record in the blog


I don't even know how to phrase the question. I have a blog with a feed. When a person clicks through to the show page, I would like to have a link with the image to the next article in a right sidebar. When it gets to the first article in the database or the newest one I either don't want a link with a picture or maybe one to the oldest story in the databse to loop back around.

I have code working where it gets the next article and displays its cover photo with a link to it. If somone could help me write the conidtion for the first article in the databse so I don't get errors that'd be great. Here's the code I have:

the show page:

  <div id="next-story-sidebar">
      <%= link_to "next story", @next_home_blog, style: "font-size:20px;" %>
      <%= image_tag @next_home_blog.image.to_s, style: "width:60px;height:60px;" %>
  </div>

home_blog.rb

def next
    self.class.where("id > ?", id).first
  end

  def previous
    self.class.where("id < ?", id).last
  end

  def last
    self.class.where("id = ?", id).last 
  end



   home_blogs_controller.rb 

  def show
    @home_blog = HomeBlog.find(params[:id])
    @next_home_blog = @home_blog.next
  end

error when I click the next story link which takes me to the first article in the database: undefined method `image' for nil:NilClass


Solution

  • It is because you need a base case for your queries.

    self.class.where("id > ?", id).first

    The issue is that if you have id of 1,2,3 and you are on number 3. This will return a 0 length collection and first on an empty collection it is nil.

    To fix this you can either do nil checking everywhere in your app

    <% if @next_home_blog %>
      <div id="next-story-sidebar">
        <%= link_to "next story", @next_home_blog, style: "font-size:20px;" %>
        <%= image_tag @next_home_blog.image.to_s, style: "width:60px;height:60px;" %>
      </div>
    <% end %>
    

    Or do something where you return a NullBlog to represent that concept and handle it more OO style. Here is a link to the NullObject pattern to get you starting if you want to investigate that. https://robots.thoughtbot.com/rails-refactoring-example-introduce-null-object