Search code examples
ruby-on-railsmodellink-to

Restrict link to previous record only if within same associated resource


I have Lesson and Word models, where a lesson has many words. In each lesson view, users can access show views for those words that belong to the lesson.

I've implemented "Previous" and "Next" links for my show view, following the ideas from this post. However, the first word of a lesson shows a "Previous" link, which links to another lesson's last word; a lesson's last word similarly links to the first word of another lesson (the only exceptions are the database's very first and very last words). How can I restrict the previous/next links only to those words that belong to the current lesson?

Word model:

class Word < ActiveRecord::Base
  belongs_to :lesson

  def previous
    Word.where(["id < ?", id]).last
  end

  def next
    Word.where(["id > ?", id]).first
  end
end

Word show view:

<div class="col-xs-10 col-xs-offset-1">
  <h1 class="text-center"><%= current_word.term %></h1><br>

  <%= image_tag(current_word.image, class: 'img-responsive') %><br>

  <p class="text-center">(<%= current_word.reference %>)</p><br>

  <%= link_to "< Previous", current_word.previous if current_word.previous %>
  <%= link_to "Next >", current_word.next if current_word.next %>
</div>

Words controller:

class WordsController < ApplicationController
  def show
  end

  private

    helper_method :current_word
    def current_word
      @current_word ||= Word.find(params[:id])
    end
end

Solution

  • Can you do something like this in your view:

    <% if current_word == Word.first %>
      <%= link_to "Next >", current_word.next if current_word.next %>
    <% elsif current_word == Word.last %>
      <%= link_to "< Previous", current_word.previous if current_word.previous %>
    <% else %>
      <%= link_to "< Previous", current_word.previous if current_word.previous %>
      <%= link_to "Next >", current_word.next if current_word.next %>
    <% end %>
    

    Edit

    So try,

    <%= link_to "< Previous", current_word.previous if current_word.previous.lesson_id == current_word.lesson.id %>
    <%= link_to "Next >", current_word.next if current_word.next.lesson_id == current_word.lesson.id %>
    

    This way as soon as either next or previous words are from a different lesson, ie have a different lesson_id, the link will disappear.

    Let me know if that works