Skip to content

feat: .^create on belongs-to relationship with auto FK#596

Open
hermes-fco wants to merge 4 commits into
FCO:masterfrom
hermes-fco:feature/create-from-relationship
Open

feat: .^create on belongs-to relationship with auto FK#596
hermes-fco wants to merge 4 commits into
FCO:masterfrom
hermes-fco:feature/create-from-relationship

Conversation

@hermes-fco

Copy link
Copy Markdown

What

Port and fix of PR #523 (from 2021).

Enables calling .^create directly on a belongs-to relationship accessor, with automatic foreign key management:

my $ble = Ble.^create(:value<ble>);
my $bla = $ble.bla.^create(:value<bla>);  # FK auto-set on $ble!

Changes

1. Fix: ast-value .ref in relationship-ast

String model references now work correctly (Red::AST::Eq.new: $_, ast-value .ref: $t2)

2. Add parent/join-on to alias role

Enables tracking the parent object for FK auto-set during create.

3. Enhance .^create metamodel method

When invoked on a relationship alias (has join-on + parent), creates the related object and automatically sets the FK on the parent, then saves it.

4. Tests

  • belongs-to create with auto FK
  • Isolation between different parent instances

Files

  • lib/MetamodelX/Red/Model.rakumod — create method + alias role
  • lib/Red/Attr/Relationship.rakumod — ast-value fix
  • t/35-create.rakutest — new tests

Closes #523

Hermes Agent added 2 commits June 11, 2026 14:41
Port from PR FCO#523 (2021):

1. Fix ast-value .ref in relationship-ast — string model references
   now work correctly in relationship conditions.
   (Red::AST::Eq.new: $\_, ast-value .ref: $t2)

2. Add parent/join-on to alias role — enables tracking the
   parent object in relationships, needed for auto FK on create.

3. Enhance .^create to handle relationship accessors:
   when called via $ble.bla.^create(...), automatically sets
   the foreign key on the parent object and saves it.

4. Tests: belongs-to create with auto FK, isolation between instances.

Closes FCO#523
- String model references (:model<Name>)
- Type model references (:model(Type))
- has-one create via relationship accessor
- Multiple creates on same parent
- Create with FK already set
- Isolation between parent instances
- Extra attributes passthrough
- Unsaved parent error case
- FK default=0 edge case
- To-many .create regression checks
Comment thread lib/MetamodelX/Red/Model.rakumod Outdated
#| And Lists and/or Hashes for relationships
multi method create(\model where *.DEFINITE, *%orig-pars, :$with where not .defined) is hidden-from-backtrace is rw {
die "Cannot call .^create on a defined model." if model.DEFINITE;
multi method create(\\mo where *.DEFINITE, *%orig-pars, :$with where not .defined) is hidden-from-backtrace is rw {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Why \mo? Shouldn't it be \mo???

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Verdade! Era escaping bug — o arquivo ficou com 4 barras em vez de 1. Corrigido em 2ff9196.

Comment thread lib/MetamodelX/Red/Model.rakumod Outdated
multi method create(\model where *.DEFINITE, *%orig-pars, :$with where not .defined) is hidden-from-backtrace is rw {
die "Cannot call .^create on a defined model." if model.DEFINITE;
multi method create(\\mo where *.DEFINITE, *%orig-pars, :$with where not .defined) is hidden-from-backtrace is rw {
my \\model = mo.^orig;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Should it be a single \???

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Mesmo problema de escaping. Corrigido junto.

Hermes Agent added 2 commits June 11, 2026 15:53
…e expected)

- t/35-create.rakutest: :default(0) → :default{ 0 } fixes 'Type check failed in assignment to &!default'
- lib/Red/Column.rakumod: .perl() → .raku()
- lib/Red/Model.rakumod: .get_value(self).perl → .get_value(self).raku
- lib/X/Red/Exceptions.rakumod: $.orig-exception.perl → $.orig-exception.raku
- lib/Red/Driver/Mock.rakumod: $re.perl() → $re.raku()
- lib/Red/Cli.rakumod: %pars.map(*.perl) → %pars.map(*.raku)
- lib/Red/Driver.rakumod: @bind.perl()/@binds.perl() → @bind.raku()/@binds.raku()
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.

2 participants