- 
                Notifications
    You must be signed in to change notification settings 
- Fork 3
[203]: add model relations property annotations #208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds model relations property annotations to Laravel models by generating @property annotations for relationships. The implementation adds support for both single and collection-based relationships with appropriate type hints.
- Adds @propertyannotations for model relationships in generated models
- Imports Illuminate\Database\Eloquent\Collectionwhen collection-type relations are present
- Generates proper type hints for singular (Model|null) and plural (Collection|Model) relationships
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
| File | Description | 
|---|---|
| stubs/model.blade.php | Adds conditional import for Collection class when collection-type relations exist | 
| src/Generators/ModelGenerator.php | Implements logic to generate relation annotations and determine Collection import necessity | 
| tests/fixtures/ModelGeneratorTest/*.php | Test fixtures showing expected output with relation property annotations | 
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
        
          
                src/Generators/ModelGenerator.php
              
                Outdated
          
        
      | foreach ($relations as $relation) { | ||
| $relation = class_basename($relation); | ||
|  | ||
| $result[$this->getRelationName($relation, $type)] = $this->getRelationType($relation, $type); | 
    
      
    
      Copilot
AI
    
    
    
      Oct 16, 2025 
    
  
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method getRelationName() is being called but is not defined in this class. This will cause a fatal error when the code is executed.
        
          
                src/Generators/ModelGenerator.php
              
                Outdated
          
        
      | protected function getRelationType(string $relation, string $type): string | ||
| { | ||
| if (in_array($type, self::PLURAL_NUMBER_REQUIRED)) { | ||
| return "Collection|$relation"; | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return "Collection|$relation"; | |
| return "Collection<{$relation}>"; | 
        
          
                src/Generators/ModelGenerator.php
              
                Outdated
          
        
      | $relation = class_basename($relation); | ||
|  | ||
| $result[$this->getRelationName($relation, $type)] = $this->getRelationType($relation, $type); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's try to refactor it to prevent code duplication (the same logic already exists in the prepareRelations)
refs: #203
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| 'User.php' => file_get_contents(getcwd() . '/tests/Support/Models/WelcomeBonus.php'), | ||
| 'Forum/Author.php' => file_get_contents(getcwd() . '/tests/Support/Models/WelcomeBonus.php'), | ||
| ]; | ||
| if (!empty ($models)) { | 
    
      
    
      Copilot
AI
    
    
    
      Oct 20, 2025 
    
  
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the space between !empty and the opening parenthesis. The correct syntax is !empty($models).
| if (!empty ($models)) { | |
| if (!empty($models)) { | 
        
          
                src/Generators/ModelGenerator.php
              
                Outdated
          
        
      | 'entity' => $this->model, | ||
| ]); | ||
|  | ||
| // TODO: use ronasit/larabuilder instead | 
    
      
    
      Copilot
AI
    
    
    
      Oct 20, 2025 
    
  
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the extra spaces before the TODO comment. Use consistent indentation with // followed by a single space.
| // TODO: use ronasit/larabuilder instead | |
| // TODO: use ronasit/larabuilder instead | 
        
          
                src/Generators/ModelGenerator.php
              
                Outdated
          
        
      | $import = "use {$import};"; | ||
|  | ||
| if (!Str::contains($classContent, $import)) { | ||
| // TODO: use ronasit/larabuilder instead | 
    
      
    
      Copilot
AI
    
    
    
      Oct 20, 2025 
    
  
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the extra spaces before the TODO comment. Use consistent indentation with // followed by a single space.
| // TODO: use ronasit/larabuilder instead | |
| // TODO: use ronasit/larabuilder instead | 
        
          
                src/Generators/ModelGenerator.php
              
                Outdated
          
        
      | { | ||
| $annotation = "* @property {$propertyDataType} \${$propertyName}"; | ||
|  | ||
| // TODO: use ronasit/larabuilder instead | 
    
      
    
      Copilot
AI
    
    
    
      Oct 20, 2025 
    
  
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the extra spaces before the TODO comment. Use consistent indentation with // followed by a single space.
| // TODO: use ronasit/larabuilder instead | |
| // TODO: use ronasit/larabuilder instead | 
        
          
                src/Generators/ModelGenerator.php
              
                Outdated
          
        
      | protected function getRelationType(string $model, string $relation): string | ||
| { | ||
| if (in_array($relation, self::PLURAL_NUMBER_REQUIRED)) { | ||
| return "Collection<int, $model>"; | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return "Collection<int, $model>"; | |
| return "Collection<{$model}>"; | 
| * @property Carbon $published_at | ||
| * @property array $meta | ||
| * @property Comment|null $comment | ||
| * @property Collection<int, User> $users | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| * @property Collection<int, User> $users | |
| * @property Collection<User> $users | 
|  | ||
| //TODO: add @property annotation for each model's field | ||
| /** | ||
| * @property Collection<int, User> $users | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| * @property Collection<int, User> $users | |
| * @property Collection<User> $users | 
|  | ||
| /** | ||
| * @property string $title | ||
| * @property Collection<int, Author> $authors | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| * @property Collection<int, Author> $authors | |
| * @property Collection<Author> $authors | 
| * @property Carbon $published_at | ||
| * @property array $meta | ||
| * @property Comment|null $comment | ||
| * @property Collection<int, User> $users | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| * @property Collection<int, User> $users | |
| * @property Collection<User> $users | 
|  | ||
| //TODO: add @property annotation for each model's field | ||
| /** | ||
| * @property Collection<int, Category> $categories | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| * @property Collection<int, Category> $categories | |
| * @property Collection<Category> $categories | 
        
          
                tests/ModelGeneratorTest.php
              
                Outdated
          
        
      | public function testAddPropertyAnnotationToRelatedModel() | ||
| { | ||
| $this->mockFilesystem([ | ||
| 'Post.php' => $this->getFixture('new_model_without_fields.php'), | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
may we just add the Post model to the mockFilesystem method?
| } | ||
|  | ||
| public function mockFilesystem(): void | ||
| public function mockFilesystem(array $models = []): void | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's implement it as separate methods
- public function mockFilesystem(array $models = []): void
- public function mockDefaultFilesystem(): void
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| public function mockFilesystem(): void | ||
| public function mockFilesystem(array $models = []): void | ||
| { | ||
| $fileSystemMock = new FileSystemMock; | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| $fileSystemMock = new FileSystemMock; | |
| $fileSystemMock = new FileSystemMock(); | 
ref: https://www.php-fig.org/psr/psr-12/#4-classes-properties-and-methods
| public function mockDefaultFilesystem(): void | ||
| { | ||
| $fileSystemMock = new FileSystemMock(); | ||
| $fileSystemMock = new FileSystemMock; | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| $fileSystemMock = new FileSystemMock; | |
| $fileSystemMock = new FileSystemMock(); | 
ref: https://www.php-fig.org/psr/psr-12/#4-classes-properties-and-methods
refs: #203