diff --git a/docs-v2/content/en/api/relations.md b/docs-v2/content/en/api/relations.md index 050e498d..c644a623 100644 --- a/docs-v2/content/en/api/relations.md +++ b/docs-v2/content/en/api/relations.md @@ -13,7 +13,46 @@ Restify handles all relationships and gives you an expressive way to list resour ## Definition -The list of relationships should be defined into a repository method called `related`: +### Option 1: Using the `fields` method (Recommended) + +You can define relationships directly within your `fields` method alongside regular fields. Restify will automatically detect eager fields and handle them as relationships: + +```php +public function fields(RestifyRequest $request): array +{ + return [ + field('id')->readonly(), + field('name')->storingRules('required'), + field('email')->storingRules('required', 'unique:users'), + + // Relationships - automatically detected and handled + belongsToMany('roles', RoleRepository::class), + hasMany('posts', PostRepository::class), + belongsTo('company', CompanyRepository::class), + + field('created_at')->readonly(), + ]; +} +``` + +Using the helper functions: + +```php +belongsTo('relationship', RepositoryClass::class) +belongsToMany('relationship', RepositoryClass::class) +hasOne('relationship', RepositoryClass::class) +hasMany('relationship', RepositoryClass::class) +morphTo('relationship') +morphOne('relationship', RepositoryClass::class) +morphMany('relationship', RepositoryClass::class) +morphToMany('relationship', RepositoryClass::class) +morphedByMany('relationship', RepositoryClass::class) +``` + + +### Option 2: Using the `related` method + +Alternatively, you can define relationships using the traditional `related` method: ```php public static function related(): array diff --git a/src/Exceptions/Solutions/OpenAiSolution.php b/src/Exceptions/Solutions/OpenAiSolution.php index 0b913c72..24af2986 100644 --- a/src/Exceptions/Solutions/OpenAiSolution.php +++ b/src/Exceptions/Solutions/OpenAiSolution.php @@ -18,17 +18,16 @@ public function __construct(protected Throwable $throwable) now()->addHour(), fn () => OpenAI::chat()->create([ 'model' => config('restify.ai_solutions.model', 'gpt-4.1-mini'), - 'messages' => + 'messages' => [ [ - [ - 'role' => 'user', - 'content' => $this->generatePrompt($this->throwable), - ], - [ - 'role' => 'system', - 'content' => 'Provide a concise solution to the problem described, tailored for a Laravel application using the Restify framework. Avoid explanations, examples, or code snippets. Respond with only the direct answer.', - ], + 'role' => 'user', + 'content' => $this->generatePrompt($this->throwable), ], + [ + 'role' => 'system', + 'content' => 'Provide a concise solution to the problem described, tailored for a Laravel application using the Restify framework. Avoid explanations, examples, or code snippets. Respond with only the direct answer.', + ], + ], 'max_tokens' => config('restify.ai_solutions.max_tokens', 1000), 'temperature' => 0, ])->choices[0]->message->content diff --git a/src/Repositories/Repository.php b/src/Repositories/Repository.php index dcec17bb..d01b0a37 100644 --- a/src/Repositories/Repository.php +++ b/src/Repositories/Repository.php @@ -248,8 +248,14 @@ public function collectFields(RestifyRequest $request): FieldCollection $method = 'fieldsForUpdateBulk'; } + $allFields = $this->filter($this->{$method}($request)); + + $regularFields = array_filter($allFields, function ($field) { + return ! ($field instanceof EagerField); + }); + return FieldCollection::make( - array_values($this->filter($this->{$method}($request))) + array_values($regularFields) )->merge( $this->extraFields($request) )->setRepository($this); diff --git a/src/Traits/InteractWithSearch.php b/src/Traits/InteractWithSearch.php index dd5ab2f8..a4eca859 100644 --- a/src/Traits/InteractWithSearch.php +++ b/src/Traits/InteractWithSearch.php @@ -3,6 +3,7 @@ namespace Binaryk\LaravelRestify\Traits; use Binaryk\LaravelRestify\Eager\RelatedCollection; +use Binaryk\LaravelRestify\Fields\EagerField; use Binaryk\LaravelRestify\Filters\AdvancedFiltersCollection; use Binaryk\LaravelRestify\Filters\Filter; use Binaryk\LaravelRestify\Filters\MatchesCollection; @@ -46,7 +47,22 @@ public static function include(): array public static function collectRelated(): RelatedCollection { - return RelatedCollection::make(static::include()); + $related = static::include(); + + if (empty($related)) { + $instance = new static; + $request = app(RestifyRequest::class); + $fields = $instance->fields($request); + + $eagerFields = collect($fields) + ->filter(fn ($field) => $field instanceof EagerField) + ->mapWithKeys(fn ($field) => [$field->attribute => $field]) + ->toArray(); + + $related = $eagerFields; + } + + return RelatedCollection::make($related); } public static function matches(): array diff --git a/src/helpers.php b/src/helpers.php index f6e7298f..515ebb1e 100644 --- a/src/helpers.php +++ b/src/helpers.php @@ -73,3 +73,52 @@ function currentRepository(): Repository return app(RepositoryInstance::class)->current(); } } + +if (! function_exists('belongsTo')) { + function belongsTo(string $attribute, string $repository): Binaryk\LaravelRestify\Fields\BelongsTo + { + return Binaryk\LaravelRestify\Fields\BelongsTo::make($attribute, $repository); + } +} + +if (! function_exists('belongsToMany')) { + function belongsToMany(string $attribute, string $repository): Binaryk\LaravelRestify\Fields\BelongsToMany + { + return Binaryk\LaravelRestify\Fields\BelongsToMany::make($attribute, $repository); + } +} + +if (! function_exists('hasOne')) { + function hasOne(string $attribute, string $repository): Binaryk\LaravelRestify\Fields\HasOne + { + return Binaryk\LaravelRestify\Fields\HasOne::make($attribute, $repository); + } +} + +if (! function_exists('hasMany')) { + function hasMany(string $attribute, string $repository): Binaryk\LaravelRestify\Fields\HasMany + { + return Binaryk\LaravelRestify\Fields\HasMany::make($attribute, $repository); + } +} + +if (! function_exists('morphOne')) { + function morphOne(string $attribute, string $repository): Binaryk\LaravelRestify\Fields\MorphOne + { + return Binaryk\LaravelRestify\Fields\MorphOne::make($attribute, $repository); + } +} + +if (! function_exists('morphMany')) { + function morphMany(string $attribute, string $repository): Binaryk\LaravelRestify\Fields\MorphMany + { + return Binaryk\LaravelRestify\Fields\MorphMany::make($attribute, $repository); + } +} + +if (! function_exists('morphToMany')) { + function morphToMany(string $attribute, string $repository): Binaryk\LaravelRestify\Fields\MorphToMany + { + return Binaryk\LaravelRestify\Fields\MorphToMany::make($attribute, $repository); + } +}