models/Post.php
public function scopeApplySibling($query, $options = [])
    {
        if (!is_array($options)) {
            $options = ['direction' => $options];
        }

        extract(array_merge([
            'direction' => 'next',
            'attribute' => 'published_at'
        ], $options));

        $isPrevious = in_array($direction, ['previous', -1]);
        $directionOrder = $isPrevious ? 'asc' : 'desc';
        $directionOperator = $isPrevious ? '>' : '<';

        $query->where('id', '<>', $this->id);

        if (!is_null($this->$attribute)) {
            $query->where($attribute, $directionOperator, $this->$attribute);
        }

        return $query->orderBy($attribute, $directionOrder);
    }
public function scopeApplySibling($query, $options = [])
    {
        if (!is_array($options)) {
            $options = ['direction' => $options];
        }

        extract(array_merge([
            'direction' => 'next',
            'attribute' => 'published_at'
        ], $options));

        $isPrevious = in_array($direction, ['previous', -1]);
        $directionOrder = $isPrevious ? 'asc' : 'desc';
        $directionOperator = $isPrevious ? '>' : '<';

        $query->where('id', '<>', $this->id);

        if (!is_null($this->$attribute)) {
            $query->where($attribute, $directionOperator, $this->$attribute);
        }

        return $query->orderBy($attribute, $directionOrder);
    }
public function scopeApplySibling ( $ query , $ options = [ ] ) { if ( ! is_array ( $ options ) ) { $ options = [ 'direction' => $ options ] ; } extract ( array_merge ( [ 'direction' => 'next' , 'attribute' => 'published_at' ] , $ options ) ) ; $ isPrevious = in_array ( $ direction , [ 'previous' , - 1 ] ) ; $ directionOrder = $ isPrevious ? 'asc' : 'desc' ; $ directionOperator = $ isPrevious ? '>' : '<' ; $ query -> where ( 'id' , '<>' , $ this -> id ) ; if ( ! is_null ( $ this -> $ attribute ) ) { $ query -> where ( $ attribute , $ directionOperator , $ this -> $ attribute ) ; } return $ query -> orderBy ( $ attribute , $ directionOrder ) ; }
Apply a constraint to the query to find the nearest sibling

// Get the next post
Post::applySibling()->first();

// Get the previous post
Post::applySibling(-1)->first();

// Get the previous post, ordered by the ID attribute instead
Post::applySibling(['direction' => -1, 'attribute' => 'id'])->first();

@param       $query
@param array $options
@return
Apply a constraint to the query to find the nearest sibling