yiisoft / yiisoft/active-record

Static relations

Open
#17 7 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

status:under discussion
Dominant language
PHP
Stars
119
Forks
38
Avg merge
1h 11m
Merged PRs (30d)
1

Description

Currently relationship definitions in AR are defined as non static getters. In reality an AR class represents a table and an instance of that class represents a record.

Relations are defined at the table level, but because AR uses non-static getters our query classes need to instantiate a dummy model for greedy queries.

Requirements for AR relationships:

  • One definition for lazy and greedy loading
  • Support (cached) retrieval via magic getter
  • Support getting a query object (currently via the getter that defines it)

Pros of current approach:

  • Uses "native" magic getters (with a small extension)
  • Has code completion for the getters since they are normal functions

Cons:

  • No way to get the relationships without instantiating a dummy model
  • No way to enumerate relations

In Yii1 we had a single function defining the relationships but we also had the dummy model due to lack of late static binding. This allowed for enumeration but had other down sides.

What if, in Yii3 we try to get the best of both? Suppose we define relationships as static functions:

public static function relatedCustomers()
{
    return Has::many (Customer::class, ['id' => 'customer_id']);
}

Internally we would have a sound definition of the relationship, from this we can:

  • build a lazy query
  • build a greedy query
  • enumerate via reflection

From a consumer point of view nothing changes:

  • getCustomers via __invoke()
  • ->customers via __get()

Pros:

  • Relations are now static
  • No need for dummy instances
  • OO definition of relationship unrelated to the query object

Cons:

  • no auto complete for the getter, so could require additional annotations.
  • breaks BC

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Review the current non-static relationship definitions and the dummy-model path, then trace the proposed static relationship entry point using Has::many(), __invoke(), __get(), and reflection. Done means the requirements for shared lazy and greedy loading, cached magic-getter access, query access, and relation enumeration are resolved without the dummy model.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
databases
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.