TheRealJAG's avatar

Pagination links() method doesn't exist after sortByDesc on hasMany

While writing a "Top" questions page in my app today I noticed that pagination isn't working ("Method links does not exist. ") when I sort on a hasMany relationship.

    /**
     * Returns relevant questions sorted by vote according to the tag object
     * @param $tags - Tags object returned from get_tags()
     * @return mixed
     */
    public static function recent_relevant_top($tags) {

            // Convert $tags object to array for whereIn()
            $tag_array = array();
            foreach($tags as $object)
                $tag_array[] = $object->name;

            $questions = Question::join('tags_questions', 'tags_questions.question_id', '=', 'questions.id')
                ->join('tags', 'tags.id', '=', 'tags_questions.tag_id')
                ->select('questions.*')
                ->whereIn('tags.name', $tag_array)
                ->orderBy('questions.id', 'desc')
                ->paginate(5);

            $questions = $questions->sortByDesc(function ($questions) {
            return $questions->votes->sum('vote');
        });

        return $questions;
    }

The query and pagination works till I get here. Script returns Method links does not exist...

    $questions = $questions->sortByDesc(function ($questions) {
            return $questions->votes->sum('vote');
        });

Why am I losing the ability to paginate when I sortByDesc?

0 likes
7 replies
TheRealJAG's avatar

@vipin93 The query works fine, when I sort the result set with sortByDesc is where I'm running into trouble.

divanoli's avatar

@TheRealJAG How are you loading the Votes relationship on the questions? Try loading Question::with('votes').

TheRealJAG's avatar

@divanoli In the question model.

public function votes() {
        return $this->hasMany('App\Vote');
    }

This will sort the results, but I'm not using pagination

public static function recent_relevant_top($tags) {

            // Convert $tags object to array for whereIn()
            $tag_array = array();
            foreach($tags as $object)
                $tag_array[] = $object->name;

            $questions = Question::join('tags_questions', 'tags_questions.question_id', '=', 'questions.id')
                ->join('tags', 'tags.id', '=', 'tags_questions.tag_id')
                ->select('questions.*')
                ->with('votes')
                ->orderBy('questions.id', 'desc')
                ->get();

            $questions = $questions->sortByDesc(function ($questions) {
            return $questions->votes->sum('vote');
        });

        return $questions;
    }
->get(); // sorted but not paginated
->paginate(5)  //will sort, but gives me 'method links does not exist.'  if I use $questions->links() in my blade.

I don't understand why I lose access to the ->links method after running.

$questions = $questions->sortByDesc(function ($questions) {
            return $questions->votes->sum('vote');
        });

Am I losing access to the object due to the callback?

divanoli's avatar

@TheRealJAG Do you want to use pagination or not? Also why would you assign the sorted questions on questions itself?

Why not just return like this?

$questions = Question::join('tags_questions', 'tags_questions.question_id', '=', 'questions.id')
                ->join('tags', 'tags.id', '=', 'tags_questions.tag_id')
                ->select('questions.*')
                ->with('votes')
                ->orderBy('questions.id', 'desc')
                ->get();

            return $questions->sortByDesc(function ($questions) {
                       return $questions->votes->sum('vote'); 
            });

TheRealJAG's avatar

@divanoli I do want pagination. I fixed the variable assign issue on my end thanks. Is the links() method not available after running sortByDesc?

Please or to participate in this conversation.