Skip to content

Realize Active Record models generator - #151

Merged
Tigrov merged 65 commits into
masterfrom
claude/generate-active-record-models
Apr 12, 2026
Merged

Realize Active Record models generator#151
Tigrov merged 65 commits into
masterfrom
claude/generate-active-record-models

Conversation

@Claude

@Claude Claude AI commented Apr 4, 2026

Copy link
Copy Markdown
Contributor

Issue #147

@Claude Claude AI assigned Claude and Tigrov Apr 4, 2026
@Claude Claude AI linked an issue Apr 4, 2026 that may be closed by this pull request
Claude AI and others added 3 commits April 4, 2026 08:04
- Add optional parameters to Command for property visibility, getters/setters, relations, and traits
- Enhance Column class with default value handling and helper methods
- Create Relation class to represent database relationships
- Improve Generator with better type mapping (int, float, bool) and relation generation
- Update default template to support all new features
- Add comprehensive test coverage for new functionality
- Create enhanced test database schema with various column types and relations

Agent-Logs-Url: https://github.com/yiisoft/yii-gii/sessions/70800279-d97a-44c7-8b35-caa2159e0744

Co-authored-by: Tigrov <8563175+Tigrov@users.noreply.github.com>
@Claude Claude AI changed the title [WIP] Improve Active Record model generation Enhance ActiveRecord generator with advanced model generation features Apr 4, 2026
@Claude
Claude AI requested a review from Tigrov April 4, 2026 08:08
Comment thread src/Generator/ActiveRecord/Generator.php Outdated
Comment thread src/Generator/ActiveRecord/Generator.php Outdated
Comment thread src/Generator/ActiveRecord/default/model.php Outdated
Comment thread src/Generator/ActiveRecord/Column.php Outdated
@Tigrov

Tigrov commented Apr 4, 2026

Copy link
Copy Markdown
Member

@claude[agent] See my review comments

…rface for DB expressions, and set() for relation columns

- Use reflection on ColumnInterface::phpTypecast() return type to determine PHP type
- Check default value using instanceof ExpressionInterface instead of string matching
- Track columns used in relationships and use ActiveRecord::set() for their setters
- Fix array default value handling to use var_export() for proper representation

Agent-Logs-Url: https://github.com/yiisoft/yii-gii/sessions/37a0f7b8-949f-4180-8839-77ca52a68c64

Co-authored-by: Tigrov <8563175+Tigrov@users.noreply.github.com>
@Claude Claude AI changed the title Enhance ActiveRecord generator with advanced model generation features Addressing PR comments Apr 4, 2026
@Claude
Claude AI requested a review from Tigrov April 4, 2026 09:04

@Tigrov Tigrov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread src/Generator/ActiveRecord/Generator.php Outdated
Comment thread src/Generator/ActiveRecord/Generator.php Outdated
…type support

- Remove fallback to $columnSchema->getPhpType() method which doesn't exist
- Add support for ReflectionUnionType by extracting the first non-null type
- Add support for ReflectionIntersectionType (returns 'mixed')
- Default to 'string' if reflection fails completely

Agent-Logs-Url: https://github.com/yiisoft/yii-gii/sessions/c185468b-b761-4cab-b415-6cf5df8a8fbd

Co-authored-by: Tigrov <8563175+Tigrov@users.noreply.github.com>
@Claude
Claude AI requested a review from Tigrov April 4, 2026 09:11

@Tigrov Tigrov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread src/Generator/ActiveRecord/Generator.php Outdated
Comment thread src/Generator/ActiveRecord/Generator.php Outdated
- Add ColumnInterface import and use it for type hints in getPhpType() and hasDbDefaultExpression()
- Replace isAllowNull() with !isNotNull() as isAllowNull() doesn't exist
- Improve type safety with proper method signatures

Agent-Logs-Url: https://github.com/yiisoft/yii-gii/sessions/c777132a-aa01-45a2-afb6-4369b20dcf39

Co-authored-by: Tigrov <8563175+Tigrov@users.noreply.github.com>
@Claude
Claude AI requested a review from Tigrov April 4, 2026 09:18
@Tigrov

Tigrov commented Apr 4, 2026

Copy link
Copy Markdown
Member

@claude[agent] Fix tests

Copilot AI left a comment

Copy link
Copy Markdown

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 15 out of 16 changed files in this pull request and generated 5 comments.

Comments suppressed due to low confidence (1)

src/Generator/ActiveRecord/Generator.php:107

  • getModelFile() always writes to @src/Model/ regardless of the namespace provided in the command/CLI. This makes the --namespace option (and the command hint about storing in the related directory) misleading and can produce files in the wrong PSR-4 path. Consider deriving the output directory from $command->namespace (or adding an explicit output directory option, like the controller generator does).
    private function getModelFile(Command $command): string
    {
        $directory = '@src/Model/';

        return $this->aliases->get(

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/Command/ActiveRecordCommand.php Outdated
Comment thread tests/Command/ActiveRecordCommandTest.php
Comment on lines +69 to +83
/**
* Returns true if this is a hasOne relation.
*/
public function isHasOne(): bool
{
return true;
}

/**
* Returns true if this is a hasMany relation.
*/
public function isHasMany(): bool
{
return false;
}

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isHasOne()/isHasMany() are currently hard-coded (true/false), so isHasMany() is dead code and relation generation can never produce hasMany. Either implement cardinality detection (e.g., based on unique indexes/PK on the FK columns) or remove these methods and the branching to avoid a misleading API.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for another PR

Comment on lines +71 to +75
if ($command->generateRelations) {
foreach ($schema->getForeignKeys() as $foreignKey) {
$relations[] = new Relation($foreignKey, $command->getModelName());
}

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relation generation only iterates $schema->getForeignKeys() for the current table, which covers only outgoing FKs. That means models won’t get inverse relations (incoming FKs / hasMany side) unless the DB schema happens to define a reverse FK too. If Issue #147 expects inverse relations, consider also scanning other tables for foreign keys that reference the current table and generating those as hasMany/hasOne accordingly.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This task for another PR

Comment thread src/Command/BaseGenerateCommand.php Outdated
Tigrov and others added 6 commits April 8, 2026 14:06
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…dels' into claude/generate-active-record-models

Copilot AI left a comment

Copy link
Copy Markdown

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 17 out of 18 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

src/Generator/ActiveRecord/Generator.php:19

  • The class-level docblock still says this generator creates a controller and action view files, but this is the ActiveRecord model generator. Updating the description would avoid misleading users and keep docs consistent with behavior.
/**
 * This generator will generate a controller and one or a few action view files.
 */

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/Helper.php
Comment thread src/Helper.php Outdated
Comment thread src/Generator/ActiveRecord/Command.php Outdated

Copilot AI left a comment

Copy link
Copy Markdown

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 17 out of 18 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

src/Generator/ActiveRecord/Generator.php:19

  • The class-level docblock still states that this generator produces controllers and view files, which is misleading for an ActiveRecord model generator. Please update it to describe ActiveRecord model generation (properties, defaults, relations, etc.) so the documentation matches the actual behavior.
/**
 * This generator will generate a controller and one or a few action view files.
 */

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/Helper.php
Comment thread src/Generator/ActiveRecord/Command.php
Comment thread src/Generator/ActiveRecord/default/model.php

Copilot AI left a comment

Copy link
Copy Markdown

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 17 out of 18 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +32 to +46
#[Required]
#[Regex(
pattern: '/^[a-z\\\\]*$/i',
message: 'Only word characters and backslashes are allowed.',
pattern: '/^\\\\?[a-z_]\w*(?:\\\\[a-z_]\w*)*$/i',
message: 'Invalid base class name',
skipOnEmpty: true,
)]
#[ClassExistsRule]
private readonly string $baseClass = ActiveRecord::class,
#[Required(message: 'A code template must be selected.')]
#[TemplateRule]
protected string $template = 'default',
public readonly string $baseClass = ActiveRecord::class,
#[Required]
#[In(['private', 'protected', 'public'])]
public readonly string $propertyVisibility = 'protected',
public readonly bool $generateGettersSetters = true,
public readonly bool $generateRelations = true,
public readonly bool $useRepositoryTrait = false,
string $template = 'default',

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The generated model code assumes the chosen $baseClass implements ActiveRecord APIs such as set(), relation(), relationQuery(), hasOne() / hasMany(). However, the command validation currently only checks that the class exists, not that it extends/implements the required ActiveRecord base/interface. This can lead to generated code that fatals at runtime if a user provides a different base class. Consider adding a validation rule to enforce a compatible base class (e.g., is_subclass_of($baseClass, ActiveRecordInterface::class)), or conditionally generating relation/setter code only when supported.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for another PR

@Tigrov
Tigrov marked this pull request as ready for review April 12, 2026 08:08
@Tigrov
Tigrov merged commit a85abef into master Apr 12, 2026
21 of 25 checks passed
@Tigrov
Tigrov deleted the claude/generate-active-record-models branch April 12, 2026 08:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generate Active Record models

5 participants