laravel-json-api / laravel

JSON:API for Laravel applications
MIT License
534 stars 42 forks source link

Eloquent model to non-eloquent entity relation #104

Open zlodes opened 3 years ago

zlodes commented 3 years ago

Hello!

I want to make a relation from Eloquent model to non-eloquent. Is it possible?

Thanks.

lindyhopchris commented 3 years ago

Hmmm, not strictly worked this one out yet. If you only need it to appear when serialising to JSON then that's possible by using a Resource class and doing it via the relationships in that. However anything more complex I haven't worked out yet. You'd probably need to ship a your own relationship field type for the schema.

Are you able to investigate using your use case? I'm unlikely to have much time to help out at the moment as I've recently started a new job.

zlodes commented 3 years ago

I tried to make my-own ToMany-based relationship class but it's not allowed:

Expecting relationships pipelineSteps to be an Eloquent JSON API to-many relationship.

Ok. I'm gonna try to use Resource class. Is it possible to add some objects to relationships section of response?

lindyhopchris commented 3 years ago

Yeah so that error is an indication I'm going to have to write a specific field to use for these scenarios.

The resource class is fully documented, so just refer to those docs...

zlodes commented 3 years ago

Thanks!

bbprojectnet commented 3 years ago

I have same issue, I work around it creating the custom action for eloquent resource, for example:

        $server
            ->resource('doctors', \App\Http\Controllers\Api\V1\DoctorController::class)
            ->only('index', 'show', 'update')
            ->relationships(function (Relationships $relationships) {
                $relationships->hasOne('user')->only('related', 'show');
                // $relationships->hasMany('visit-dates')->only('related', 'show');
            })
            ->actions(function (ActionRegistrar $actions) {
                $actions->withId()->get('visit-dates', 'readVisitDates'); // non-eloquent pseudo relation
            });

eloquent resource resource:

    public function relationships($request): iterable
    {
        $relationships = iterator_to_array(parent::relationships($request));

        return array_merge($relationships, [
            $this->relation('visit-dates'),
        ]);
    }

and the controller:

    public function readVisitDates(AnonymousQuery $query, DoctorSchema $schema, Doctor $doctor): Responsable
    {
        $schema = JsonApi::server()->schemas()->schemaFor('visit-dates');

        $models = $schema
            ->repository()
            ->queryAll()
            ->withRequest($query)
            ->withDoctor($doctor)
            ->get();

        return DataResponse::make($models);
    }

but also I would be grateful for built-in solution :)

DellanX commented 6 months ago

Has there been any movement on this?

I have a calendar model that has events which are stored in an ICalendar format. So I need to be able to pull the non-eloquent data when querying /calendars/{calendar}/events

I'd definitely be willing to PR and experiment, just need to know a little more about the desired direction here.

lindyhopchris commented 6 months ago

Sharing the response I put on the new issue that was opened in the Eloquent repository: https://github.com/laravel-json-api/eloquent/issues/33#issuecomment-1962392924