0
votes

In the show (html) page I have this

<% if  @movie.views_count > 150 && @movie.ratings_chart_last_days(30) < 4 %>
    You are in the first 3 positions
<% end %>

and in movie.rb I have this

  def ratings_chart_last_days(number_of_days)
    subset = Movie.where('movies.created_at >= ?', number_of_days.days.ago)
    @ratings_chart_last_days ||= chart_position(:ratings_abs, subset)
  end

But I have this report:

undefined method `<' for nil:NilClass

the ratings_chart_last_days method is returning nil. Then when it tries to do a < comparison it tries to execute the < method. NilClass doesn't support that method.

How to solve?!

EDITED

Chart_position code

module Chartable
  def chart_position(attribute, start_query = nil)
    attribute = self.class.connection.quote_column_name(attribute.to_s)
    partition = partition_by(start_query || self.class.all, attribute)
    self.class.from(partition, :s).select('s.id, s.position')
        .find_by('s.id = ?', id).try(:position)
  end

  private

  def partition_by(chain, attribute)
    chain
      .select('id, ROW_NUMBER() OVER ('\
              "ORDER BY #{attribute} DESC, created_at DESC"\
              ') as position')
  end
end
2
Ensure that ratings_chart_last_days never returns nil - mrzasa
Can you please paste the code for chart_position too? - Samy Kacimi
@SamyKacimi added - J.Luca

2 Answers

0
votes

Since your method ratings_chart_last_days might return nil, you can change it to:

def ratings_chart_last_days(number_of_days)
  subset = Movie.where('movies.created_at >= ?', number_of_days.days.ago)
  @ratings_chart_last_days ||= chart_position(:ratings_abs, subset)
  @ratings_chart_last_days ||= 0 # Just added
end
0
votes

I'm not sure what your intent is here but if you're only looking at movies created in the last 30 days and you have none, I suspect chart_position method might return nil?

You could either force it to be considered in the top three positions or force it to be considered unranked, your choice. To include it in the the top position, return 0 otherwise return Float::INFINITY

def ratings_chart_last_days(number_of_days)
  @ratings_chart_last_days ||= {}
  return @ratings_chart_last_days[number_of_days] if @ratings_chart_last_days[number_of_days].present?
  subset = Movie.where('movies.created_at >= ?', number_of_days.days.ago)
  @ratings_chart_last_days[number_of_days] ||= chart_position(:ratings_abs, subset) || Float::INFINITY
end

I've also changed your memoization... you were always returning @ratings_chart_last_days regardless of the number_of_days argument, so I've suggested that @ratings_chart_last_days should be a hash of all previously calculated results, indexed by number_of_days