0
votes

I have a model called customers which has a custom attribute called name; this can either by a customers full name or the company name depending on what their account type is.

class Customer extends Model
{

    const BUSINESS = "Business";
    const INDIVIDUAL = "Individual";

    protected $table = 'users';
    protected $appends = ['name'];
    private $name;

    public static function boot()
    {
        parent::boot();

        static::created(function () {
        });

        static::updating(function () {
        });
    }


    /**
     * Get the display name for the customer
     * 
     * if Customer::BUSINESS then use company field
     * else if Customer::INDIVIDUAL then use their name
     * 
     * @return mixed|string
     */
    function getDisplayName() {
        return ($this->account == Customer::BUSINESS) ? $this->company : $this->getContactName();
    }

    public function getContactName()
    {
        return ucfirst($this->first_name) . " " . ucfirst($this->last_name);
    }

    /**
     * @return mixed
     */
    public function getName()
    {
        return $this->getDisplayName();
    }

    /**
     * @param mixed $name
     */
    public function setName($name)
    {
        $this->name = $name;
    }
}

I want to be able to ORDER BY this custom attribute if possible.

At the moment Laravel throws an error saying name is not a defined column.

Is there a way to do this with Laravel Query builder?

2

2 Answers

5
votes

You will not be able to use this attribute in a query without converting this function into a SQL statement.

You can however query this model and sort it afterward using the sortBy function. This will order your collection in memory after it has been fetched from the database.

$customers = Customers::get()->sortBy('name');

Keep in mind that this is not recommended for large collections (> ~10k). Then you should look into converting this to an SQL statement.

0
votes

To improve on @tomaytotomato answer you can reduce memory usage and execution time by using the Laravel cursor() method

$customers = Customers::cursor()->sortBy('name');