MorphicPro
MorphicPro

Reputation: 2902

RoR | how to find the next and previous based on a date

I'm trying to look up 1 instance of a model via a slug, which I can do via

@project = Project.where(:slug => params[:id]).first

But once I get the instance I want to find the next and previous instances of the model from a order of a column called publish which is a date.

how would I get the slug only of the previous and next instance of my arbitrary order by column?

::Edit:: Adding this to my modeled worked.

def previous(offset = 0)     
  self.class.select('slug').first(:conditions => ['published < ?', self.id], :limit => 1,        :offset => offset, :order => "published DESC")
end

def next(offset = 0)
  self.class.select('slug').first(:conditions => ['published > ?', self.id], :limit => 1, :offset => offset, :order => "published ASC")
end

I found this solution at Next, Previous Records Using Named Scope

Upvotes: 2

Views: 581

Answers (1)

Jordan Running
Jordan Running

Reputation: 106027

Assuming your publish dates are unique something like this ought to work:

@project = Project.where(:slug => params[:id]).first

@prev_project = Project.where( "publish < ?", @project.publish ).
                        order( "publish DESC" ).
                        first

@next_project = Project.where( "publish > ?", @project.publish ).
                        order( "publish" ).
                        first

For @prev_project the where clause indicates all Projects before @project, the order lists them latest first (which puts the one right before @project at the top) and first limits the query to one result, i.e. the previous Project. The query for @next_project is the same but reversed. If publish isn't unique you'll have to sort on a second criterium as well.

However, you may want to consider not reinventing the wheel and using the very common gem acts_as_list, which would make this as simple as @project.higher_item and @project.lower_item.

Upvotes: 8

Related Questions