Alex Zakruzhetskyi
Alex Zakruzhetskyi

Reputation: 1433

Works fine on localhost, but not on heroku

I have a problem on heroku, when I try to access my posts. The logs says:

Rendered posts/index.html.erb within layouts/application (920.6ms)
2015-11-06T09:39:41.716328+00:00 app[web.1]: Completed 500 Internal Server Error in 936ms (ActiveRecord: 42.1ms)
2015-11-06T09:39:41.720223+00:00 app[web.1]: 
2015-11-06T09:39:41.720226+00:00 app[web.1]: ActionView::Template::Error (undefined method `email' for nil:NilClass):
2015-11-06T09:39:41.720227+00:00 app[web.1]:     22:            <dt> <%= post.body %> </dt>
2015-11-06T09:39:41.720227+00:00 app[web.1]:     23:             <dd><%= post.tags %> </dd>
2015-11-06T09:39:41.720228+00:00 app[web.1]:     24:          </dl>
2015-11-06T09:39:41.720229+00:00 app[web.1]:     25:          <%= gravatar_for post.user, size: 40%> Created by <b><%= post.user.name if post.user %></b>
2015-11-06T09:39:41.720229+00:00 app[web.1]:     26:         </td>
2015-11-06T09:39:41.720230+00:00 app[web.1]:     27: 
2015-11-06T09:39:41.720231+00:00 app[web.1]:     28:     <div>
2015-11-06T09:39:41.720231+00:00 app[web.1]:   app/helpers/users_helper.rb:3:in `gravatar_for'

On localhos:3000/posts it works good, the mistake appears only on heroku. I use PostgreSQL both in development and production.

Here is my routes.rb:

  resources :users
  resources :sessions, only: [:new, :create, :destroy]
  resources :posts
 root 'posts#index'
   match '/signup', to: 'users#new',         via: 'get'
   match '/signin', to: 'sessions#new',      via: 'get'
   match '/signout', to: 'sessions#destroy', via: 'delete'

A part of my posts#index:

<div class="show_posts">
<table>
    <% @posts.each do |post| %>

        <td>
         <dl> <%= post.title %>
           <dt> <%= post.body %> </dt>
            <dd><%= post.tags %> </dd>
         </dl>
         <%= gravatar_for post.user, size: 40%> Created by <b><%= post.user.name if post.user %></b>
        </td>

users_helper.rb:

module UsersHelper
  def gravatar_for(user, options = { size: 50 })
    gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
    size = options[:size]
    gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}?s=#{size}"
    image_tag(gravatar_url, alt: user.name, class: "gravatar")
  end
end    

Any ideas how to solve the problem?

Upvotes: 0

Views: 876

Answers (1)

Richard Peck
Richard Peck

Reputation: 76774

The problem lies inside gravatar_for, where you call...

Digest::MD5::hexdigest(user.email.downcase)

The required user object doesn't exist.

This is caused in your posts#index model, when you reference:

<%= gravatar_for post.user, size: 40%> Created by <b><%= post.user.name if post.user %>

As suggested in the comments, this is likely due to you not having an associated user object for your post.

The immediate fix will be to use some conditional logic to determine whether the user exists (which you're doing already, but only for the post.user.name output):

<% if post.user %>
    <%= gravatar_for post.user, size: 40 %> Created by <b><%= post.user.name %>
<% end %>

Alternatively, you may wish to make all posts have a user by using a validation to determine whether the associated object is set:

#app/models/user.rb
class User < ActiveRecord::Base
   has_many :posts, inverse_of: :user
end

#app/models/post.rb
class Post < ActiveRecord::Base
   belongs_to :user, inverse_of: :posts
   validates :user, present: true
end

Upvotes: 3

Related Questions