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

Eloquent firstOrCreate() doesn't work with cast attributes #12238

Closed
cviebrock opened this issue Feb 10, 2016 · 9 comments
Closed

Eloquent firstOrCreate() doesn't work with cast attributes #12238

cviebrock opened this issue Feb 10, 2016 · 9 comments

Comments

@cviebrock
Copy link
Contributor

This might be related to #5578, but if I have a model that uses $casts, then the firstOrCreate() always creates a new instance. For example:

class MyModel extends \Illuminate\Database\Eloquent\Model {

  $casts = [
    'field' => 'array'
  ];
}

$data = [
  'field' => [1,2,3]
];

// creates a new model
$model = MyModel::firstOrCreate($data); 

//...

// also creates a new model instead of retrieving the first one
$model2 = MyModel::firstOrCreate($data);
@cviebrock
Copy link
Contributor Author

Further infomation: The "find" part of firstOrCreate doesn't use cast attributes, but the "create" part does. So, unfortunately I can't even manually cast them before passing it to firstOrCreate (otherwise my array is manually cast to a string, and then cast to another string by Laravel).

@crazycodr
Copy link

It would be my first real contribution but i'll try to fix this one and see the impacts, i can't set myself as assignee though since i do not have write access to this!

@crazycodr
Copy link

I've studied the code mostly the query builder and model/builder part. If you were to always do:

MyModel::where(['data' => [1,2,3])
//or
MyModel::where('data', '=', [1,2,3])

Then it would be feasible, but problem is that if you where to start a query from another point in the chain, then it wouldn't be possible because you would be in the context of the query and at that point we do not have the reference to the model (i think, can't be sure) but just the table name. This means we cannot cast asJson the values passed to the where at that point...

Mutators and casts are operational at the model level not the query builder level. There is maybe a way to query using a model such as creating a getRawAttributeValue function that returns the already casted / mutated value but then again, because of mutators which may alter many attributes at once, you never know if something else was modified also:

$myModel = new MyModel();
$myModel->data = [1,2,3];
$raw = $myModel->getRawAttributeValue('data');
var_dump(MyModel::where('data', $raw)); //Would work

I'll wait for another contributor before implementing this as there is probably something better that i'm not aware of.

Note: I tried my potential solution but i got a really weird problem i can't seem to diagnose. When i use a cast to json, my end data in the database looks like "[1,, 2,, 3]" and not the standard "[1,2,3]" notation from json_encode. I'm not sure where this comes from, is it because of the different changes it tried to do to fix it but something's weird!

@assada
Copy link

assada commented Apr 21, 2016

Also Eloquent firstOrCreate() doesn't work with fillable attributes too

@kyranb
Copy link

kyranb commented Jun 8, 2016

I've just run into the same issue as @assada using firstOrCreate with a date property.

@reedmaniac
Copy link

Also just ran into this issue where attribute mutators are not taken into account with firstOrNew(). So, watching this thread.

@Dylan-DPC-zz
Copy link

I think you can close this issue and reopen it if you find it in 5.5

@reedmaniac
Copy link

The code has not changed in 5.5. I am still curious if this is considered a bug since there was a revert of a fix back in Aug 2016

@themsaid
Copy link
Member

Moved the discussion to laravel/ideas#856, it's very hard to say if this behaviour is wanted or not, so let's first discuss it before we say it's a bug to be fixed or is the current behaviour the one intended.

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

7 participants