Florence Liang
Florence Liang

Reputation: 87

App works fine on Localhost, but has NoMethodError (undefined method `-' for nil:NilClass) on Heroku

I am new to Ruby and now experiencing an error after deploying my app to Heroku.

I test my app on localhost and everything works fine; however, when I try to save a new post, I have "undefined method `-' for nil:NilClass" on Heroku. I have searched for solutions on StackOverflow but so far I haven't found anything.

Error I got from heroku logs:

2015-04-01T03:37:23.412066+00:00 app[web.1]: NoMethodError (undefined method `-' for nil:NilClass):
2015-04-01T03:37:23.412076+00:00 app[web.1]:   app/controllers/topics/posts_controller.rb:22:in `create'
2015-04-01T03:37:23.412074+00:00 app[web.1]:   app/models/post.rb:37:in `save_with_initial_vote'
2015-04-01T03:37:23.407819+00:00 app[web.1]:    (1.0ms)  ROLLBACK
2015-04-01T03:37:23.412070+00:00 app[web.1]:   app/models/vote.rb:20:in `update_post'
2015-04-01T03:37:23.412078+00:00 app[web.1]: 
2015-04-01T03:37:23.412063+00:00 app[web.1]: 
2015-04-01T03:37:23.412068+00:00 app[web.1]:   app/models/post.rb:30:in `update_rank'
2015-04-01T03:37:23.412072+00:00 app[web.1]:   app/models/post.rb:39:in `block in save_with_initial_vote'

From the logs, it looks like the problem is from update_rank method in post.rb.

From my app/models/post.rb:

  class Post < ActiveRecord::Base
  has_many :comments, dependent: :destroy
  has_many :votes, dependent: :destroy
  has_many :favorites, dependent: :destroy
  belongs_to :user
  belongs_to :topic

  default_scope { order('rank DESC') }
  scope :visible_to, ->(user) { user ? all : joins(:topic).where('topics.public' => true) }

  validates :title, length: { minimum: 5 }, presence: true
  validates :body, length: { minimum: 20 }, presence: true
  validates :topic, presence: true
  validates :user, presence: true

    def update_rank
        age_in_days = (created_at - Time.new(1970,1,1)) / (60 * 60 * 24)
        new_rank = points + age_in_days

        update_attribute(:rank, new_rank)
      end

      def save_with_initial_vote
        ActiveRecord::Base.transaction do
          post = Post.create
          user.votes.create(value: 1, post: self)
        end
      end

From app/controllers/topics/posts_controller.rb:

  def create
    @topic = Topic.find(params[:topic_id])
    @post = current_user.posts.build(post_params)
    @post.topic = @topic
        authorize @post

    if @post.save_with_initial_vote
      flash[:notice] = "Post was saved."
      redirect_to [@topic, @post]
    else
      flash[:error] = "There was an error saving the post. Please try again."
      render :new
    end
  end

models/vote.rb:

after_save :update_post

  def up_vote?
    value == 1
  end

  def down_vote?
    value == -1
  end

  def update_post
    post.update_rank
  end

I have run "heroku rn db:migrate" and "heroku restart" but the error still exists. My rails version is 4.2.0 and my Ruby version is 2.0.0.

Does anyone know what is the cause and how to make it work on Heroku?

Upvotes: 0

Views: 395

Answers (1)

Steve Wilhelm
Steve Wilhelm

Reputation: 6260

The only use of "-" in the code provided is in first line of Post#update_rank

Note, when I run the following in irb

irb> (nil - Time.new(1970,1,1)) / (60  * 60 * 24) 

I get the following error.

NoMethodError: undefined method `-' for nil:NilClass

Remember everything in Ruby a class. Many classes implement the operator methods. The DateTime class does, but the NilClass does not.

I suspect your created_at is not yet set and at this point is a nil value.

Upvotes: 1

Related Questions