Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to order results #28

Closed
ariselseng opened this issue Mar 22, 2017 · 3 comments
Closed

Ability to order results #28

ariselseng opened this issue Mar 22, 2017 · 3 comments

Comments

@ariselseng
Copy link

Hi,
This is a great package and it is really helping my project.
One thing I miss is the ability to order results based on query parameters.

Any thoughts?

@Tucker-Eric
Copy link
Owner

I have run into a similar issue and initially was just passing sort_col and sort_dir to the query and then in the model filter using a sortCol() method like:

public function sortCol($col)
{
    $this->orderBy($col, $this->input('sort_dir', 'DESC'));
}

Then these methods started getting bloated when ordering by a relation that wasn't joined and having to add each relation's join query.

That eventually turned into:

public function sortCol($col)
{
    if(method_exists($this, $method = 'orderBy'.studly_case($col))) {
        return $this->$method();
    }

    $this->orderBy($col, $this->input('sort_dir', 'DESC'));
}

public function orderByClientNumber()
{
    $this->join('clients', 'clients.user_id', '=', 'users.id')
        ->orderBy('clients.work_phone', $this->input('sort_dir', 'DESC'));
}

I'm not sure I like that solution though...

I'm totally open to suggestions on this one as it's been coming up a bit more frequently for me.

@philliphartin
Copy link

philliphartin commented Jun 18, 2017

@Tucker-Eric I like the method you've provided, I actually added an additional if statement around the pure orderBy() method to ensure that the column being requested exists.

 /**
     * Sort the Items by a specific column
     * Optionally sort in a specific direction
     * @param $column
     * @return mixed
     */
    public function sortBy($column)
    {

        // Check if pre-defined orderBy method exists to sort by
        if (method_exists($this, $method = 'orderBy' . studly_case($column))) {
            return $this->$method();
        }

        // Otherwise order by the column in a specific direction, default DESC
        if(Schema::hasColumn('items', $column)){
            return $this->orderBy($column, $this->input('sort_direction', 'DESC'));
        }

    }

Only issue is that the table name needs to be included. Perhaps there is a cleaner way?

@Tucker-Eric
Copy link
Owner

I would define an orderable method on the filter to be able to tune it per model/filter/query and fallback to a default sort. Something like:

protected $sortable = ['created_at', 'updated_at', 'id'];

public function sortable($column)
{
    return in_array($column, array_merge($this->getModel()->getFillable(), $this->sortable));
}

Then you can do:

 /**
 * Sort the Items by a specific column
 * Optionally sort in a specific direction
 * @param $column
 * @return mixed
 */
public function sortBy($column)
{

    // Check if pre-defined orderBy method exists to sort by
    if (method_exists($this, $method = 'orderBy' . studly_case($column))) {
        return $this->$method();
    }

    // Otherwise order by the column in a specific direction, default DESC
    return $this->sortable($column) ? $this->orderBy($column, $$this->input('sort_direction', 'DESC')) : $this->orderBy('created_at', 'DESC')
}

That way you're not adding another query to check for the existence of a column and you are reverting back to your default when the column isn't recognized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants