Comments (11)
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.
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.
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.
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.
Can you explain to an outsider, why the hydration of a newly created resource would be different from an existing?
from laravel-json-api.
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.
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.
When updating a resource, how does it know to call hydrateSomethingRelationship
? Does it simple traverse the relationships
object?
from laravel-json-api.
@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.
Did you need anything from me, on this one?
from laravel-json-api.
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)
- Unable to create json api resource with attribute name "type" HOT 3
- Self-relation doesn't include model fields HOT 5
- Arguement 3 passed to controller must be an instance of model, string given
- Support for multiple operations in a single request HOT 2
- use Errors Handling in Laravel 8 HOT 1
- Why does json-api trimming spaces in my attributes when updating? HOT 3
- filter slug and underscore HOT 1
- Multiple primary keys - Mysql Error HOT 1
- Sparse fieldsets not working with included relationships HOT 3
- How to attach a middleware to a specific resource relationship? HOT 3
- How I can filter included resources by their fields HOT 8
- Migrate from cloudcreativity/laravel-json-api to laravel-json-api/laravel HOT 15
- How to stop this library from making asterix queries? HOT 1
- Make a request to one endpoint from another controller HOT 5
- Insert on duplicate key upd when inserting a record? HOT 6
- Handle HasMany relationship with extra field. HOT 2
- [5.x] Missing meta HOT 8
- bug: service provider boot throws "No application encryption key has been specified." HOT 1
- Error in tests HOT 1
- getResourceLinks function HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from laravel-json-api.