How do I find the next and previous lesson?
I am currently building an LMS and am looking to add in the ability for the user to navigate to the next lesson.
In the admin back end when a teacher adds a lesson they are able to give it a position, this helps lay the lessons out. I sort on both position and then by title. So the learner can see the whole list of lessons, including topics within a lesson.
Now when the user views a lesson, I want to have the functionality for the learner to be able to click next lesson button. This will mark the current lesson as viewed and also navigate to the next lesson.
What is the best way to go about this?
I have looked and have seen the following suggestions
@next_lesson = @course.lessons.where("position > ?", @lesson.position).order(:position).first
This will work as long as every lesson has a unique position set. Sometimes this may not be the case, imagine a scenario where the teacher thinks of a lesson which would be better suited to the start of the course and he wants to add this to the beginning adding the postion of 2 this would fail as there is already a lesson with this value. Would they then need to change every lesson position value to add this position in?
Not sure what the best way to do this would be? Suggestions are welcome, especially if I have missed something very obvious.
Models for Course, Lesson and Topic are shown below, but this is just standard stuff.
class Course < ApplicationRecord
belongs_to :author, class_name: 'User', foreign_key: 'author_id'
has_many :lessons
end
class Lesson < ApplicationRecord
belongs_to :author, class_name: 'User', foreign_key: 'author_id'
belongs_to :course
has_many :topics
end
class Topic < ApplicationRecord
belongs_to :author, class_name: 'User', foreign_key: 'author_id'
belongs_to :lesson
end
The acts_as_list gem has some methods for inserting and moving items in a list. It updates all the values afterward if you were to insert an item at position 2 like you mentioned. You'd need to make those updates in a transaction so it would undo all of them if any one failed.
In fact, you might just want to use that gem. It comes in handy so you don't have to reinvent the wheel on any of that.