{"id":15041740,"url":"https://github.com/yii2tech/ar-eagerjoin","last_synced_at":"2025-10-04T05:31:19.676Z","repository":{"id":57087047,"uuid":"51099685","full_name":"yii2tech/ar-eagerjoin","owner":"yii2tech","description":"ActiveRecord behavior, which provides relation eager loading by join without extra query","archived":true,"fork":false,"pushed_at":"2019-07-03T10:50:29.000Z","size":37,"stargazers_count":22,"open_issues_count":0,"forks_count":3,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-01-14T22:51:51.310Z","etag":null,"topics":["activerecord","eager-loading","join","yii","yii2","yii2-extension"],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yii2tech.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["klimov-paul"],"patreon":"klimov_paul"}},"created_at":"2016-02-04T19:27:03.000Z","updated_at":"2023-10-07T23:59:46.000Z","dependencies_parsed_at":"2022-08-20T15:31:14.695Z","dependency_job_id":null,"html_url":"https://github.com/yii2tech/ar-eagerjoin","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yii2tech%2Far-eagerjoin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yii2tech%2Far-eagerjoin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yii2tech%2Far-eagerjoin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yii2tech%2Far-eagerjoin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yii2tech","download_url":"https://codeload.github.com/yii2tech/ar-eagerjoin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235222543,"owners_count":18955327,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["activerecord","eager-loading","join","yii","yii2","yii2-extension"],"created_at":"2024-09-24T20:46:25.866Z","updated_at":"2025-10-04T05:31:14.401Z","avatar_url":"https://github.com/yii2tech.png","language":"PHP","funding_links":["https://github.com/sponsors/klimov-paul","https://patreon.com/klimov_paul"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/yii2tech\" target=\"_blank\"\u003e\n        \u003cimg src=\"https://avatars2.githubusercontent.com/u/12951949\" height=\"100px\"\u003e\n    \u003c/a\u003e\n    \u003ch1 align=\"center\"\u003eActiveRecord Eager Join Extension for Yii 2\u003c/h1\u003e\n    \u003cbr\u003e\n\u003c/p\u003e\n\nThis extension provides support for ActiveRecord relation eager loading via 'join' without extra query.\n\nFor license information check the [LICENSE](LICENSE.md)-file.\n\n[![Latest Stable Version](https://poser.pugx.org/yii2tech/ar-eagerjoin/v/stable.png)](https://packagist.org/packages/yii2tech/ar-eagerjoin)\n[![Total Downloads](https://poser.pugx.org/yii2tech/ar-eagerjoin/downloads.png)](https://packagist.org/packages/yii2tech/ar-eagerjoin)\n[![Build Status](https://travis-ci.org/yii2tech/ar-eagerjoin.svg?branch=master)](https://travis-ci.org/yii2tech/ar-eagerjoin)\n\n\nInstallation\n------------\n\nThe preferred way to install this extension is through [composer](http://getcomposer.org/download/).\n\nEither run\n\n```\nphp composer.phar require --prefer-dist yii2tech/ar-eagerjoin\n```\n\nor add\n\n```json\n\"yii2tech/ar-eagerjoin\": \"*\"\n```\n\nto the require section of your composer.json.\n\n\nUsage\n-----\n\nThis extension provides support for ActiveRecord relation eager loading via 'join' without extra query.\nImagine we have the following database structure:\n\n```sql\nCREATE TABLE `Group`\n(\n   `id` integer NOT NULL AUTO_INCREMENT,\n   `name` varchar(64) NOT NULL,\n   `code` varchar(10) NOT NULL,\n    PRIMARY KEY (`id`)\n) ENGINE InnoDB;\n\nCREATE TABLE `Item`\n(\n   `id` integer NOT NULL AUTO_INCREMENT,\n   `groupId` integer NOT NULL,\n   `name` varchar(64) NOT NULL,\n   `price` float,\n    PRIMARY KEY (`id`)\n    FOREIGN KEY (`groupId`) REFERENCES `Group` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,\n) ENGINE InnoDB;\n```\n\nIf you need to display listing of items, with the groups they belong to, ordered by group name or code,\nyou'll have to use `JOIN` SQL statement and thus - `\\yii\\db\\ActiveQuery::joinWith()` method:\n\n```php\n$items = Item::find()\n    -\u003ejoinWith('group')\n    -\u003eorderBy(['{{group}}.[[name]]' =\u003e SORT_ASC])\n    -\u003eall();\n```\n\nHowever, the code above will perform 2 SQL queries: one - for the item fetching (including `JOIN` and\n`ORDER BY` statements) and second - for the group fetching. While second query will be very simple and fast,\nit is still redundant and unefficient, since all group columns may be selected along with the item ones.\n\nThis extension provides [[yii2tech\\ar\\eagerjoin\\EagerJoinTrait]] trait, which, once used in the\nActiveRecord class, allows selecting related records without extra SQL query.\n\nSetup example:\n\n```php\nuse yii\\db\\ActiveRecord;\nuse yii2tech\\ar\\eagerjoin\\EagerJoinTrait;\n\nclass Item extends ActiveRecord\n{\n    use EagerJoinTrait;\n\n    public function getGroup()\n    {\n        return $this-\u003ehasOne(Group::className(), ['id' =\u003e 'groupId']);\n    }\n}\n```\n\nIn order to populate related record though 'join' query, you'll need to manually append its columns\ninto the `SELECT` query section and alias them by names in following format:\n\n```\n{relationName}{boundary}{columnName}\n```\n\nwhere:\n\n - 'relationName' - name of the relation to be populated\n - 'columnName' - name of the column(attribute) of the related record to be filled\n - 'boundary' - separator configured by [[yii2tech\\ar\\eagerjoin\\EagerJoinTrait::eagerJoinBoundary()]]\n\nFor example:\n\n```php\n$items = Item::find()\n    -\u003eselect(['Item.*', 'group__name' =\u003e 'Group.name', 'group__code' =\u003e 'Group.code'])\n    -\u003ejoinWith('group', false) // disable regular eager loading!!!\n    -\u003eall();\n\nforeach ($items as $item) {\n    var_dump($item-\u003eisRelationPopulated('group')); // outputs `true`!!!\n    echo $item-\u003egroup-\u003ename; // no extra query performed!\n    echo $item-\u003egroup-\u003ecode; // no extra query performed!\n    echo get_class($item-\u003egroup); // outputs 'Group'!\n}\n```\n\nHere 'group__name' column of the query result set is passed to `$item-\u003egroup-\u003ename`, 'group__code' -\nto `$item-\u003egroup-\u003ecode` and so on.\n\n**Heads up!** Do not forget to disable eager loading, passing `false` as second argument of `joinWith()`\nmethod, otherwise you'll gain no benefit.\n\n\u003e Note: choose `boundary` carefully: it should not be present as a part of the columns (or aliases), which\n  are not meant to be passed to the related records. Thus double underscore ('__') is used as default.\n\n\u003e Tip: if you use 'camelCase' notation for your table columns, you may use single underscore ('_') as a\n  boundary in order to make select statements more clear.\n\nYou may speed up composition of the query for the eager join using [[\\yii2tech\\ar\\eagerjoin\\EagerJoinQueryTrait]] trait.\nThis trait should be used in the [[\\yii\\db\\ActiveQuery]] instance:\n\n```php\nuse yii\\db\\ActiveQuery;\nuse yii2tech\\ar\\eagerjoin\\EagerJoinQueryTrait;\nuse yii\\db\\ActiveRecord;\nuse yii2tech\\ar\\eagerjoin\\EagerJoinTrait;\n\nclass ItemQuery extends ActiveQuery\n{\n    use EagerJoinQueryTrait;\n\n    // ...\n}\n\nclass Item extends ActiveRecord\n{\n    use EagerJoinTrait;\n\n    /**\n     * @inheritdoc\n     * @return ItemQuery the active query used by this AR class.\n     */\n    public static function find()\n    {\n        return new ItemQuery(get_called_class());\n    }\n\n    // ...\n}\n```\n\nThen you'll be able to use `eagerJoinWith()` method while building a query:\n\n```php\n$items = Item::find()-\u003eeagerJoinWith('group')-\u003eall();\n```\n\nComposition of the proper 'select' and 'join' statements will be performed automatically.\n\n\n## Restrictions and drawbacks \u003cspan id=\"restrictions-and-drawbacks\"\u003e\u003c/span\u003e\n\nWhile reducing the number of executed queries, this extension has several restrictions and drawbacks.\n\n1) Only 'has-one' relations are supported. Extension is unable to handle 'has-many' relations.\nYou should use regular `joinWith()` and eager loading for 'has-many' relations.\n\n2) If all selected related model fields will be `null`, the whole related record will be set to `null`.\nYou should always select at least one 'not null' column to avoid inappropriate results.\n\n3) Despite extra query removal, this extension may not actually increase overall performance.\nRegular Yii eager join query is very simple and fast, while this extension consumes extra memory and performs\nextra calculations. Thus in result performance remain almost the same. In most cases usage of this extension is\na tradeoff: it reduces load on Database side, while increases it on PHP side.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyii2tech%2Far-eagerjoin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyii2tech%2Far-eagerjoin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyii2tech%2Far-eagerjoin/lists"}