ruby-on-railsrails-activerecord

Next Instance Method


In my blog app, I can call @article.comments.last. How do I create a next_comment method, one that always picks the next comment in line?

Update: Also, how do I do the reverse, define a previous_comment method?

Update answer below.

Previous record:

  class Comment < ActiveRecord::Base
    def self.previous(comment, key = :id)
      self.where("#{key} < ?", commend.send(key)).first
    end
end

Solution

  • In order to define a "next", you must declare a sorting rule. There is no "next" without an order.

    The order can be as simple as by primary key, or another field (e.g. a name). The following method should support both cases, and default to "id"

    class Comment < ActiveRecord::Base
      def self.next(comment, key = :id)
        self.where("#{key} > ?", comment.send(key)).first
      end
    end
    

    You should call it on the chain and pass the comment instance, so that it can use the same relation you used to load the original comment

    scope = @article.comments
    last = scope.last
    next = scope.next(last)
    

    Another (maybe simpler) solution is to simply load two objects

    current, next = @article.comments.take(2)
    

    You can also make it a method

    class Comment < ActiveRecord::Base
      def self.first_and_next
        # use all to create a scope in case you call
        # the method directly on the Comment class
        all.take(2)
      end
    end
        
    current, next = @article.comments.first_and_next(2)