I have a resource named posts, of which there are many. However, each post can have multiple tags. I want users to be able to go to the previous post and next post, ONLY from the tag that was selected. I have it working for all posts from the database in previous next, but when I click on a tag and it shows all the tags, prev/next doesn't adhere to what the tag is.
If I visit the url in association with the code defined in routes.rb,   get 'tags/:tag', to: 'posts#index', as: :tag, it'll list all the tags in an index. I don't want this, I want a user to be able to click previous or next and only do so on posts that are associated with a tag. 
Note: I am using the friendly_id gem
controllers/posts_controller.rb
  def index
    @posts = Post.all
    if params[:tag]
      @posts = Post.tagged_with(params[:tag])
    else
      @posts = Post.all
    end
  end
models/post.rb
# tags 
  acts_as_taggable # Alias for acts_as_taggable_on :tags
def next
    Post.where("id > ?", id).order(id: :asc).limit(1).first
end
def prev
     Post.where("id < ?", id).order(id: :desc).limit(1).first
end
show.html.erb
<%= link_to "← Previous Question", @post.prev, :class => 'button previous-question' %>
<%= link_to "Next Question →", @post.next, :class => 'button next-question' %>
routes.rb
 # TAGS
  get 'tags/:tag', to: 'posts#index', as: :tag
                I think you are going to have to pass around that tag parameter (although you should probably make it a helper method)
models/post.rb
def next tag
  Post.where("id > ?", id).tagged_with(tag).order(id: :asc).limit(1).first
end
def prev tag
  Post.where("id < ?", id).tagged_with(tag).order(id: :desc).limit(1).first
end
show
<%= link_to "← Previous Question", post_path(@post.prev(current_tag).id, tag: current_tag), :class => 'button previous-question' %>
<%= link_to "Next Question →", post_path(@post.next(current_tag).id, tag: current_tag), :class => 'button next-question' %>
controllers/posts_controller.rb
class PostsController < ApplicationController
  helper_method :current_tag
  #def show
  #def index
  private
  def current_tag
    params[:tag]
  end
end
                        Here is updated Sean's answer. It should work now. The problem appears when prev or next methods returning nil
models/post.rb
def next tag
  result = Post.where("id > ?", id).tagged_with(tag).order(id: :asc).limit(1).first
  result || very_first(tag)
end
def prev tag
  result = Post.where("id < ?", id).tagged_with(tag).order(id: :desc).limit(1).first
  result || very_last(tag)
end
def very_first tag
  Post.tagged_with(tag).order(id: :asc).limit(1).first
end
def very_last tag
  Post.tagged_with(tag).order(id: :asc).limit(1).last
end
show
<% if @post.prev(current_tag) %>
  <%= link_to "← Previous Question", post_path(@post.prev(current_tag).id, tag: current_tag), :class => 'button previous-question' %>
<% end %>
<% if @post.next(current_tag) %>
  <%= link_to "Next Question →", post_path(@post.next(current_tag).id, tag: current_tag), :class => 'button next-question' %>
<% end %>
controllers/posts_controller.rb
class PostsController < ApplicationController
  helper_method :current_tag
  #def show
  #def index
  private
  def current_tag
    params[:tag]
  end
end
P.S. sorry Sean, I can't comment on your answer, so I just copied and fixed it
You can put this in your controller then, Post.where(["id < ?", id]).last for previous and Post.where(["id > ?", id]).first this for next. 
What you are trying to do is the job of the controller. You can extend those based on your sorting.
I also found this gem. Would be much better for you to use.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With