Lazlo
Lazlo

Reputation: 8780

How can I access attributes using camel case?

To be consistent over my coding style, I'd like to use camelCase to access attributes instead of snake_case. Is this possible in Laravel without modifying the core framework? If so, how?

Example:

// Database column: first_name

echo $user->first_name; // Default Laravel behavior
echo $user->firstName; // Wanted behavior

Upvotes: 28

Views: 22072

Answers (3)

pwyg
pwyg

Reputation: 779

Just thought I'd post this in case it helps anyone else. Though the answer by Bouke is great it does not address lazy-loaded relations that use a camel-case name. When this occurs we simply need to check for the method name in addition to the other checks. The following is what I did:

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class BaseModel extends Model
{

    public function getAttribute($key)
    {

        if (
            array_key_exists($key, $this->relations)
            || method_exists($this, $key)
        ) {
            return parent::getAttribute($key);
        } else {
            return parent::getAttribute(Str::snake($key));
        }
    }

    public function setAttribute($key, $value)
    {
        return parent::setAttribute(Str::snake($key), $value);
    }
}

Upvotes: 6

Bouke Versteegh
Bouke Versteegh

Reputation: 4677

Since SO doesn't allow pasting code snippets in comments, I'm posting this as a new answer.

To make sure that eager loading does not break, I had to modify @Lazlo's answer. When accessing eagerly loaded relations by a different key, they are reloaded.

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class BaseModel extends Model
{

    public function getAttribute($key)
    {
        if (array_key_exists($key, $this->relations)) {
            return parent::getAttribute($key);
        } else {
            return parent::getAttribute(Str::snake($key));
        }
    }

    public function setAttribute($key, $value)
    {
        return parent::setAttribute(Str::snake($key), $value);
    }
}

Upvotes: 24

Lazlo
Lazlo

Reputation: 8780

Create your own BaseModel class and override the following methods. Make sure all your other models extend your BaseModel.

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class BaseModel extends Model {
    
    // Allow for camelCased attribute access
    
    public function getAttribute($key)
    {
        return parent::getAttribute(Str::snake($key));
    }
    
    public function setAttribute($key, $value)
    {
        return parent::setAttribute(Str::snake($key), $value);
    }
}

Then for usage:

// Database column: first_name

echo $user->first_name; // Still works
echo $user->firstName; // Works too!

This trick revolves around forcing the key to snake case by overriding the magic method used in Model.

Upvotes: 36

Related Questions