{"action":"created","issue":{"url":"https://api.github.com/repos/Vincit/objection.js/issues/235","repository_url":"https://api.github.com/repos/Vincit/objection.js","labels_url":"https://api.github.com/repos/Vincit/objection.js/issues/235/labels{/name}","comments_url":"https://api.github.com/repos/Vincit/objection.js/issues/235/comments","events_url":"https://api.github.com/repos/Vincit/objection.js/issues/235/events","html_url":"https://github.com/Vincit/objection.js/issues/235","id":186090476,"number":235,"title":"Default eager loading for Model class","user":{"login":"zuck","id":1370938,"avatar_url":"https://avatars.githubusercontent.com/u/1370938?v=3","gravatar_id":"","url":"https://api.github.com/users/zuck","html_url":"https://github.com/zuck","followers_url":"https://api.github.com/users/zuck/followers","following_url":"https://api.github.com/users/zuck/following{/other_user}","gists_url":"https://api.github.com/users/zuck/gists{/gist_id}","starred_url":"https://api.github.com/users/zuck/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zuck/subscriptions","organizations_url":"https://api.github.com/users/zuck/orgs","repos_url":"https://api.github.com/users/zuck/repos","events_url":"https://api.github.com/users/zuck/events{/privacy}","received_events_url":"https://api.github.com/users/zuck/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2016-10-29T17:30:58Z","updated_at":"2016-10-31T13:20:01Z","closed_at":null,"body":"Let's imagine we have two models: `Person` and `Pet`, where each `Person` could have many `Pet`s.\r\n\r\nNow let's say `Person` needs a virtual attribute, e.g. `petAddicted`, which counts the number of related `Pet`s to measure the love of each `Person` for the animals in general:\r\n\r\n```\r\nPerson.prototype.petAddicted = function() {\r\n  return this.pets.length;\r\n}\r\n\r\nPerson.virtualAttributes = ['petAddicted'];\r\n```\r\n\r\nThis virtual attribute is used everywhere: this means I have to eager load the `Pet` relation every time a `Person` is fetched, both in main or related queries and where the instance is translated to JSON format.\r\n\r\n**How this goal could be achieved? Is it currently possible?**\r\n\r\nMy idea is to associate a custom `QueryBuilder` to the `Person` model but I can't figure out where exactly I should implement the \"default eager loading\" behavior...maybe on `forClass` method?\r\n\r\nI open this issue to keep track of this feature which, IMHO, could be integrated as \"native\" in the future (e.g. adding a new static property to `Model` class, like `defaultEager`, to define default eager loading behavior in default `QueryBuilder`s):\r\n\r\n```\r\nPerson.defaultEager = ['pets'];\r\n\r\nPet\r\n.query()\r\n.findById(1)\r\n.eager('owner')\r\n.then(function(bobby) {\r\n  console.log(\"Pet addiction level: \" + bobby.owner.petAddicted);\r\n});\r\n\r\n// Pet addiction level: 5\r\n```\r\n"},"comment":{"url":"https://api.github.com/repos/Vincit/objection.js/issues/comments/257291371","html_url":"https://github.com/Vincit/objection.js/issues/235#issuecomment-257291371","issue_url":"https://api.github.com/repos/Vincit/objection.js/issues/235","id":257291371,"user":{"login":"zuck","id":1370938,"avatar_url":"https://avatars.githubusercontent.com/u/1370938?v=3","gravatar_id":"","url":"https://api.github.com/users/zuck","html_url":"https://github.com/zuck","followers_url":"https://api.github.com/users/zuck/followers","following_url":"https://api.github.com/users/zuck/following{/other_user}","gists_url":"https://api.github.com/users/zuck/gists{/gist_id}","starred_url":"https://api.github.com/users/zuck/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zuck/subscriptions","organizations_url":"https://api.github.com/users/zuck/orgs","repos_url":"https://api.github.com/users/zuck/repos","events_url":"https://api.github.com/users/zuck/events{/privacy}","received_events_url":"https://api.github.com/users/zuck/received_events","type":"User","site_admin":false},"created_at":"2016-10-31T13:20:01Z","updated_at":"2016-10-31T13:20:01Z","body":"I tried to implement it creating a custom `QueryBuilder` class and overriding the `forClass` method, but it doesn't work as expected:\r\n\r\n```\r\n// Create a custom QueryBuilder for current Model.\r\nfunction MyQueryBuilder() {\r\n  objection.QueryBuilder.apply(this, arguments);\r\n}\r\n\r\n// Basic ES6 compatible prototypal inheritance.\r\nobjection.QueryBuilder.extend(MyQueryBuilder);\r\n\r\nMyQueryBuilder.forClass = function(modelClass) {\r\n  var qb = objection.QueryBuilder.forClass.call(this, modelClass);\r\n  return qb.eager(modelClass.defaultEager || \"\");\r\n}\r\n\r\nmodel.QueryBuilder = MyQueryBuilder;\r\nmodel.RelatedQueryBuilder = MyQueryBuilder;\r\n```\r\n\r\nAll my models use this custom `MyQueryBuilder` and the trick seems to work when model instances are fetched directly, but not when they are fetched as part of a relation (related model instances are returned, but no eager loading is performed on them)."}}
{"actor":{"display_login":"zuck"}}