Git Product home page Git Product logo

Comments (11)

lindyhopchris avatar lindyhopchris commented on August 10, 2024

Yeah, you need to skip hydration if creating then use the created hook in the controller.

In your hydrator:

/**
 * @param RelationshipInterface $relationship
 * @param Post $model
 */
protected function hydrateCompaniesRelationship(RelationshipInterface $relationship, User $user)
{
    if (!$user->exists) {
        return;
    }

    $user->companies()->attach($relationship->getIdentifiers()->getIds());
}

v0.4 controller:

protected function created(Model $model)
{
    $companies = $this->getResource()->getRelationships()->getRelated('companies');
    $this->hydrator->hydrateRelationship('companies', $relationship, $model);
}

In v0.5 I need to update the event hooks in the controller to receive the resource as the second method
argument as you cannot do $this->getResource().

from laravel-json-api.

lindyhopchris avatar lindyhopchris commented on August 10, 2024

PS: happy for any suggestions if you think there's a better way of doing it, but this is working for me for any relationship where the model needs to exist first

from laravel-json-api.

egeriis avatar egeriis commented on August 10, 2024

I'm not enough into this library to suggest alternatives. But it seems a bit dirty to have to do this in the controller, as the hydrator—from my intuitive perspective—should be responsible for all hydration.

If the Hydrator knows about calling hydrateCompaniesRelationship, couldn't it act on the model created hook if model does not yet exist?

from laravel-json-api.

lindyhopchris avatar lindyhopchris commented on August 10, 2024

Yeah, good point.

I suppose there's a strong argument for this problem not being unique to Eloquent - i.e. there's a lot of database layers and abstractions that would need to do a hydration after creating the primary record.

So on that basis, I could add to the HydratorInterface a post-create hydration method for dealing with these scenarios. Then the EloquentController could automatically trigger this (probably immediately after calling $model->save() but before calling the created hook).

Not sure what to call the method, maybe hydrateCreated?

It'd require an EloquentHydrator but I was planning on putting one of those in anyway as there's already an EloquentSchema to extend.

from laravel-json-api.

egeriis avatar egeriis commented on August 10, 2024

Can you explain to an outsider, why the hydration of a newly created resource would be different from an existing?

from laravel-json-api.

lindyhopchris avatar lindyhopchris commented on August 10, 2024

Ok, thinking about it again, then all the controller needs is a list of relationships that it needs to hydrate after creating the model. (As this problem only applies to creation, not to update.)

Not sure what to call it as it applied to any HasOneOrMany Eloquent relationships, but would need to use the resource relationship name.

So maybe your controller would have this property on it:

protected $hasOneOrMany = ['companies'];

And then the EloquentController save method would loop through those and call the hydrateRelationship method on those if it has just created the model.

from laravel-json-api.

lindyhopchris avatar lindyhopchris commented on August 10, 2024

Actually it wouldn't need that property as it's already got a list of relationship mappings in the $relationships property. So it'd just need to loop through the relationships on the received resource, map the key to the Eloquent model's key, then get the relationship from the model - and if it's an instance of HasOneOrMany, invoke the hydrator's relationship method.

That makes sense to me, but realise I might not have explained it well. Basically it's possible for the controller to work this out itself. The controller needs to work it out because it knows when the save has been executed, but the hydrator does not.

I'll add to v0.4

from laravel-json-api.

egeriis avatar egeriis commented on August 10, 2024

When updating a resource, how does it know to call hydrateSomethingRelationship? Does it simple traverse the relationships object?

from laravel-json-api.

lindyhopchris avatar lindyhopchris commented on August 10, 2024

@egeriis yeah, it traverses the relationship object received from the client. The hydrator is just meant to contain the logic of transferring data from client's representation of the resource to the domain record. The controller is the thing executing the CRUD operations (which is where I believe it should be because that's kind of the role of the controller.)

https://github.com/cloudcreativity/json-api/blob/master/src/Hydrator/AbstractHydrator.php#L96

from laravel-json-api.

egeriis avatar egeriis commented on August 10, 2024

Did you need anything from me, on this one?

from laravel-json-api.

lindyhopchris avatar lindyhopchris commented on August 10, 2024

Nothing more required - thanks for your input.

I've actually solved this and the demo app has a belongsToMany relationship on the posts resource to demo how it works, which is:

I've added an interface for a hydrator to indicate that it needs to hydrate related resources as well as the "primary" resource. This is actually really useful as I have a couple of resources in one of my apps that contain attributes from a related Eloquent model, so it can be used for that purpose as well as has-many relationships:
https://github.com/cloudcreativity/json-api/blob/feature/v0.6/src/Contracts/Hydrator/HydratesRelatedInterface.php#L49

The Eloquent controller on the 0.5.x-dev branch handles hydrators that implement this interface:
https://github.com/cloudcreativity/laravel-json-api/blob/feature/v0.5/src/Http/Controllers/EloquentController.php#L283

And additionally I've added an EloquentHydrator class which uses this to hydrate belongsToMany relationships - though you don't need to use this hydrator class, you can just implement the new interface on your existing hydrator:
https://github.com/cloudcreativity/laravel-json-api/blob/feature/v0.5/src/Hydrator/EloquentHydrator.php

Putting it all together, here is the new posts hydrator in the demo app:
https://github.com/cloudcreativity/demo-laravel-json-api/blob/laravel-5.3/app/JsonApi/Posts/Hydrator.php

from laravel-json-api.

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.