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

[5.3] Allow key arguments to model getAttributes #15722

Merged
merged 1 commit into from
Oct 3, 2016
Merged

[5.3] Allow key arguments to model getAttributes #15722

merged 1 commit into from
Oct 3, 2016

Conversation

ntzm
Copy link
Contributor

@ntzm ntzm commented Oct 3, 2016

No description provided.

@taylorotwell taylorotwell merged commit 52e56cd into laravel:5.3 Oct 3, 2016
@tabennett
Copy link
Contributor

FYI, this breaks backwards compatibility with any existing 5.3 app that's overriding the getAttributes() method or using a package that does. I ran composer update and now having production sites (that were already upgraded to 5.3) breaking now.

$result = [];

foreach ($keys as $key) {
$value = $this->getAttribute($key);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using getAttribute within this method might cause some incompatibilites. When you ask all attributes, Eloquent won't cast nor use mutators in any of them; but when you specify some keys you will get them casted or mutated (if there is something to mutate). In my view, this method may cause confusion since it works one way with parameters and in a different way without parameters.

For example, let's say we have this Model:

User extends Eloquent
{
    protected $casts = [
        'active' => 'boolean'
    ];

   public function getFullNameAttribute()
   {
        return $this->first_name . ' ' . $this->last_name;
   }
}
$attributes = $model->getAttributes();

// You'll get the following without "full_name" attribute
$attributes = [
    // ...
    'active' => 1,
    'created_at' => '2016-10-07 14:47:25',
    // ...
];

This is how it comes from the database. If you use $model->getAttributes() that's what you'll get, but if you just ask for those attributes as you propose this is what you'll get:

$attributes = $model->getAttributes(['active', 'created_at', 'full_name']);

$attributes = [
    // ...
    'active' => true,
    'created_at' => new Carbon('2016-10-07 14:47:25'),
    'full_name' => 'Cristian Llanos',
    // ...
]

In this case you'll get active as a boolean, not a number and created_at as a Carbon instance since its a timestamp and Eloquent does that when you call getAttribute.

Newcomers or someone who doesn't know about this behaviour might have a hard time figuring out why this method provides different results in certain occasions.

I'm not very confident about this, but I suppose getAttributes should return us all attributes already casted or mutated as needed. However, this is not the case nowadays and for that purpose we can use $model->toArray() (which will give us all attributes casted or mutated).

tabennett added a commit to CodeSleeve/stapler that referenced this pull request Oct 7, 2016
@lucasmichot
Copy link
Contributor

@ntzm - my app is now broken...

@taylorotwell
Copy link
Member

I'll revert it.

@ntzm
Copy link
Contributor Author

ntzm commented Oct 9, 2016

Oops! Sorry guys

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

Successfully merging this pull request may close these issues.

None yet

6 participants