Giter Site home page Giter Site logo

Comments (6)

OllieCrook avatar OllieCrook commented on September 18, 2024

Hi @foremtehan,

The framework is functioning as expected here. The issue arises from the incompatibility between your get and set methods.

When you access your custom cast using $user->name, an entry is added to the classCastCache array indicating that the class cast has been used. This utilizes your get method to convert the value {"test"} into new TestCast().

However, when you call $user in Tinker or perform an action on the model, such as $user->save() to persist the data into the database, the class cannot be inserted as is; it needs to be serialized.

For normal serialization Laravel uses PHP's __sleep() magic method to prepare the model for serialization. At this point, the $this->mergeAttributesFromCachedCasts() method is called, revealing the issue with your get and set methods.

A part of this method call involves using the custom cast setter to prepare your value. The resulting code essentially does this:

return json_encode(new TestCast());

Since you haven't specified how PHP should serialize your class, perhaps by implementing JsonSerializable, it converts it as best it can, taking class TestCast {} and converting it to {}.

When creating a custom cast, ensure that the output value from your get method can always be passed into your set method and result in the expected output.

I hope this clarifies things. If you have any follow-up questions, I’d be happy to help.

from framework.

foremtehan avatar foremtehan commented on September 18, 2024

I didn't assign a value to the name column, so why would it trigger the set method on the castable class?

Additionally, note that I tested it, and the framework never invoked the set method when using ->name.

from framework.

OllieCrook avatar OllieCrook commented on September 18, 2024

It doesn't trigger the set when you access it. But when you access you add an entry to the classCastCache array (see: HasAttributes.php:879

Then later on when it needs to serialize your model it calls the set (see: Model.php:2387 for the main method and HasAttributes.php:1823 for the set call).

Try it yourself. Access it with $user->name then access it again straight after. You'll see it doesn't overwrite. It only overwrites once you serialize it.

from framework.

foremtehan avatar foremtehan commented on September 18, 2024

Overall, this is unwanted behavior. Just imagine using $user->name in your app, and then calling save() somewhere in your codebase afterward. Your data will be lost. I’ll let the maintainers decide whether to close this issue, but I have demonstrated the problem.

from framework.

OllieCrook avatar OllieCrook commented on September 18, 2024

You control how the set behaves here so it's up to you to make it work how you want it to work. If you change your get to new TestCast($value), save that value inside the class then on your set retrieve it or implement JsonSerializable you will have no problems.

The comment for the set method even tells you this..

Prepare the given value for storage.

from framework.

henzeb avatar henzeb commented on September 18, 2024

Overall, this is unwanted behavior. Just imagine using $user->name in your app, and then calling save() somewhere in your codebase afterward. Your data will be lost. I’ll let the maintainer decide whether to close this issue, but I have demonstrated the problem.

Is there a real world example of this? because in the end, get should cast to the object value you want it in, and set should use an object value to convert back to a value that can be stored in the database, which in your case isn't happening at all.

from framework.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.