Question

In my Rails 4 app, I defined functions in my model than get the (nth) next or previous row in de database, wrapping around the entire database, so that Item.last.next will refer to Item.first:

  def next(n=0)
    following = Item.where("id > ?", self.id).order("id asc") + Item.where("id < ?", self.id).order("id asc")
    following[n % following.length]
  end

  def prev(n=0)
    n = n % Item.count-1
    previous = Item.where("id < ?", self.id).order("id desc") + Item.where("id > ?", self.id).order("id desc")
    previous[n % previous.length]
  end

This results in three database queries per method call, and I've learned to keep database queries to a minimum, so I wonder if there is a way do get this result with only one query.

Was it helpful?

Solution

What you are looking for seems a bit high level. So let's prepare the basic API at first.

def next(n=1)      
  self.class.where('id > ?', id).limit(n).order('id ASC')
end

def previous(n=1)
  self.class.where('id > ?', id).limit(n).order('id DESC')
end

Then higher level methods

def next_recycle(n=1)
  klass = self.class
  return klass.first if (n = 1 && self == klass.last)
  next(n)
end

def previous_recycle(n=1)
  klass = self.class
  return klass.last if (n == 1 && self == klass.first)
  previous(n)
end

You can pick methods according to needs.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top