Comments (12)
Okay, so first of all... DERP. I was using a performance-saving tip from the demo project which requires a Larvel belongsTo relationship. Obviously this is not that!
So the 'address' and 'addressable' relationship data should just reference the Laravel relationship directly.
Now I am working on a new error:
InvalidArgumentException: Schema is not registered for a resource at path 'building.address'. in /home/vagrant/Code/hoistway-cms/vendor/neomerx/json-api/src/Encoder/Parser/Parser.php:271
Error occurs here:
https://github.com/neomerx/json-api/blob/9acd6091fb74c9a2376ff8cd1a9613b89be353eb/src/Schema/Container.php#L146
from laravel-json-api.
hi. that new error you are getting indicates that whatever your buildings
resource is returning in the data
of its address
relationship isn't an object class that has a schema registered. do you know what class of object it is returning?
from laravel-json-api.
Well the relationship is "morphOne" intended for polymorphic relationships. The object returned is an Address. Does it have something to do with the relationship being nested?
Here is a log dump.
[2017-04-23 16:44:02] local.INFO: Building relationship: {"building":"[object] (App\Models\Building\Building: {"id":2,"name":"Fake Building"})","address_relationship":"[object] (Illuminate\Database\Eloquent\Relations\MorphOne: {})","address":"[object] (App\Models\Address\Address: {"id":16,"addressable_id":2,"addressable_type":"buildings","city_id":10344,"street":null,"street_extra":null,"postal_code":null,"email":null,"phone_mobile":null,"phone_desk":null,"phone_company":null,"phone_fax":null,"latitude":"51.0486151","longitude":"-114.0708459","place_id":"ChIJ1T-EnwNwcVMROrZStrE7bSY","created_at":"2017-02-19 17:57:26","updated_at":"2017-02-19 17:57:26","city":{"id":10344,"country_id":"CA","country_division_id":1,"name":"Calgary"},"country":{"id":"CA","name":"Canada","division_title":"Province","postal_code_title":"Postal Code"},"division":{"id":1,"country_id":"CA","code":"AB","name":"Alberta"}})"}
from laravel-json-api.
I'm not totally sure I understand the log dump. Isn't that saying thataddress_relationship
is a MorphOne
object?
from laravel-json-api.
Yes that is correct. That is how a one-for-one polymorphic relationship is defined.
from laravel-json-api.
Sorry, probably wasn't clear from my answer! Are you returning the MorphOne
object as the data element of the relationship? The exception is saying that there is no schema registered for the value that is being returned... so you're returning something that isn't an address model.
Do you get the same error if the address relationship in the buildings schema is changed from this:
'address' => [
self::SHOW_SELF => true,
self::SHOW_RELATED => true,
self::DATA => isset($includeRelationships['address']) ?
$resource->address : $this->createBelongsToIdentity($resource, 'address'),
],
to this:
'address' => [
self::SHOW_SELF => true,
self::SHOW_RELATED => true,
self::DATA => $resource->address,
],
I'll be honest, this is a little bit difficult to debug from afar!
from laravel-json-api.
I apologize for misunderstanding. Your first version above is how I had it in the first place which created the first error. I changed it to the second example of yours, which led to the second error - it seems like progress, but not enough.
From the event that is fired when a Device is created/updated/deleted, this is where the logging is occurring.
public function broadcastWith()
{
Log::info('Device event:', ['class' => self::class, 'data' => $this->device]);
Log::info('Building relationship:', ['building' => $this->device->building, 'address_relationship' => $this->device->building->address(), 'address' => $this->device->building->address]);
$this->device->load('building', 'type');
$output = Encoder::instance([
Device::class => Devices\Schema::class,
Building::class => Buildings\Schema::class,
DeviceType::class => DeviceTypes\Schema::class
])->serializeData($this->device, new EncodingParameters(['building', 'device-type']));
Log::info('Output:', ['response' => $output]);
return $output;
}
And Devices\Schema, this is the root of this request. So, the device Broadcast event is including Building, and implicitly checking the Address relationship. If I just remove the Building relationship include, then the event broadcast works.
<?php
namespace App\JsonApi\Devices;
use App\Models\Building\Device;
use CloudCreativity\JsonApi\Exceptions\RuntimeException;
use CloudCreativity\LaravelJsonApi\Schema\EloquentSchema;
class Schema extends EloquentSchema
{
/**
* @var string
*/
const RESOURCE_TYPE = 'devices';
/**
* @var array
*/
protected $attributes = [
'designation',
'group',
'licence',
'slug'
];
/**
* @return string
*/
public function getResourceType()
{
return self::RESOURCE_TYPE;
}
/**
* @param object $resource
* @param bool $isPrimary
* @param array $includeRelationships
* @return array
*/
public function getRelationships($resource, $isPrimary, array $includeRelationships)
{
if (!$resource instanceof Device) {
throw new RuntimeException('Expecting a Device model.');
}
return [
'building' => [
self::SHOW_SELF => true,
self::SHOW_RELATED => true,
self::DATA => $resource->building,
],
'device-type' => [
self::SHOW_SELF => true,
self::SHOW_RELATED => true,
self::DATA => isset($includeRelationships['device-type']) ?
$resource->type : $this->createBelongsToIdentity($resource, 'type'),
],
];
}
}
from laravel-json-api.
I added a log output to Buildings\Schema to make sure it can access the address relationship properly, which it can. I also wondered if maybe it had to do with pluralization of "address" as it is an odd case, but it seems to work, at least on Laravel's end.
As you would expect, If I comment out the data input like then it completes execution without an error.
public function getRelationships($resource, $isPrimary, array $includeRelationships)
{
if (!$resource instanceof Building) {
throw new RuntimeException('Expecting a Building model.');
}
Log::info('Address test:', ['address' => $resource->address, 'plural' => str_plural('address'), 'singular' => str_singular('addresses')]);
return [
'address' => [
self::SHOW_SELF => true,
self::SHOW_RELATED => true,
//self::DATA => $resource->address,
],
'devices' => [
self::SHOW_SELF => true,
self::SHOW_RELATED => true,
self::DATA => function () use ($resource) {
return $resource->devices;
},
]
];
}
[2017-04-24 05:04:58] local.INFO: Address test: {"address":"[object] (App\Models\Address\Address: {"id":16,"addressable_id":2,"addressable_type":"buildings","city_id":10344,"street":null,"street_extra":null,"postal_code":null,"email":null,"phone_mobile":null,"phone_desk":null,"phone_company":null,"phone_fax":null,"latitude":"51.0486151","longitude":"-114.0708459","place_id":"ChIJ1T-EnwNwcVMROrZStrE7bSY","created_at":"2017-02-19 17:57:26","updated_at":"2017-02-19 17:57:26","city":{"id":10344,"country_id":"CA","country_division_id":1,"name":"Calgary"},"country":{"id":"CA","name":"Canada","division_title":"Province","postal_code_title":"Postal Code"},"division":{"id":1,"country_id":"CA","code":"AB","name":"Alberta"}})","plural":"addresses","singular":"address"}
from laravel-json-api.
Closed by mistake only.
from laravel-json-api.
So your error is in your broadcaster. When creating the Encoder, there's no schema for the address model in the array you're passing in.
from laravel-json-api.
OOHHHHHHHHHHH! Got it. Thanks for your help!
To keep things simpler, I have just used the config file as so:
return Encoder::instance(Config::get('json-api.schemas.defaults'))->serializeData($this->device, new EncodingParameters(['building', 'device-type']));
Maybe the Encoder constructor could default to just looking up the schemas from the config file?
from laravel-json-api.
I'm going to do a broadcaster trait that allows you to load the encoder using the api name that's in the config file. That should make it easier. Glad we got your immediate problem solved!
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.