{"action":"created","issue":{"url":"https://api.github.com/repos/realm/realm-cocoa/issues/3419","repository_url":"https://api.github.com/repos/realm/realm-cocoa","labels_url":"https://api.github.com/repos/realm/realm-cocoa/issues/3419/labels{/name}","comments_url":"https://api.github.com/repos/realm/realm-cocoa/issues/3419/comments","events_url":"https://api.github.com/repos/realm/realm-cocoa/issues/3419/events","html_url":"https://github.com/realm/realm-cocoa/pull/3419","id":146765505,"number":3419,"title":"Add support for linking objects properties","user":{"login":"bdash","id":54825,"avatar_url":"https://avatars.githubusercontent.com/u/54825?v=3","gravatar_id":"","url":"https://api.github.com/users/bdash","html_url":"https://github.com/bdash","followers_url":"https://api.github.com/users/bdash/followers","following_url":"https://api.github.com/users/bdash/following{/other_user}","gists_url":"https://api.github.com/users/bdash/gists{/gist_id}","starred_url":"https://api.github.com/users/bdash/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bdash/subscriptions","organizations_url":"https://api.github.com/users/bdash/orgs","repos_url":"https://api.github.com/users/bdash/repos","events_url":"https://api.github.com/users/bdash/events{/privacy}","received_events_url":"https://api.github.com/users/bdash/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/realm/realm-cocoa/labels/Blocked%20On%20Core","name":"Blocked On Core","color":"fad8c7"},{"url":"https://api.github.com/repos/realm/realm-cocoa/labels/S:In%20Progress","name":"S:In Progress","color":"ededed"},{"url":"https://api.github.com/repos/realm/realm-cocoa/labels/T:Enhancement","name":"T:Enhancement","color":"bfe5bf"}],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/realm/realm-cocoa/milestones/3","html_url":"https://github.com/realm/realm-cocoa/milestones/0.99","labels_url":"https://api.github.com/repos/realm/realm-cocoa/milestones/3/labels","id":1564485,"number":3,"title":"0.99","description":"","creator":{"login":"jpsim","id":474794,"avatar_url":"https://avatars.githubusercontent.com/u/474794?v=3","gravatar_id":"","url":"https://api.github.com/users/jpsim","html_url":"https://github.com/jpsim","followers_url":"https://api.github.com/users/jpsim/followers","following_url":"https://api.github.com/users/jpsim/following{/other_user}","gists_url":"https://api.github.com/users/jpsim/gists{/gist_id}","starred_url":"https://api.github.com/users/jpsim/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jpsim/subscriptions","organizations_url":"https://api.github.com/users/jpsim/orgs","repos_url":"https://api.github.com/users/jpsim/repos","events_url":"https://api.github.com/users/jpsim/events{/privacy}","received_events_url":"https://api.github.com/users/jpsim/received_events","type":"User","site_admin":false},"open_issues":6,"closed_issues":2,"state":"open","created_at":"2016-02-04T21:44:30Z","updated_at":"2016-04-07T23:08:35Z","due_on":null,"closed_at":null},"comments":6,"created_at":"2016-04-07T22:55:56Z","updated_at":"2016-04-11T17:23:26Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/realm/realm-cocoa/pulls/3419","html_url":"https://github.com/realm/realm-cocoa/pull/3419","diff_url":"https://github.com/realm/realm-cocoa/pull/3419.diff","patch_url":"https://github.com/realm/realm-cocoa/pull/3419.patch"},"body":"Linking objects properties provide a live view on which objects have a given relationship with an object:\r\n```swift\r\nclass Person: Object {\r\n    dynamic var name = \"\"\r\n    dynamic var age = 0\r\n    let children = List<Person>()\r\n    let parents = LinkingObjects(fromType: Person.self, property: \"children\")\r\n}\r\n```\r\n\r\nThey're an improvement over the existing `Object.linkingObjects(_:forProperty:)` in three key ways:\r\n\r\n1. They're a live, automatically updating view, rather than a point in time snapshot.\r\n2. They can be used in queries:\r\n\r\n    ```swift\r\n    // People that have a child that have a parent named Diane.\r\n    realm.objects(Person).filter(\"ANY children.parents.name == 'Diane'\")\r\n    ```\r\n3. `LinkingObjects` is a subclass of `Results` and so supports all of methods you'd expect:\r\n\r\n    ```swift\r\n    // Which of my parents are over the age of 56?\r\n    bdash.parents.filter(\"age > 56\")\r\n    \r\n    // Calculate the age of my parents.\r\n    bdash.parents.average(\"age\")\r\n    ```\r\n\r\nFixes #1324.\r\n\r\nThis depends on an unreleased version of Realm core.\r\n\r\nRemaining work:\r\n- [ ] Schema validation to ensure that the specified class and property links to this object.\r\n- [ ] Notifications? I think these should work out of the box, but need tests to verify.\r\n- [ ] More testing of the non-query aspects.\r\n\r\nOutstanding issues:\r\n- [ ] Objective-C `RLMLinkingObjects` properties are `nil` for standalone objects, but Swift `LinkingObjects` cannot be. How should we reconcile this?\r\n- [ ] Do we need to support KVO on linking objects properties in the initial implementation?\r\n- [ ] Is there a nicer way to declare the properties in Objective-C?\r\n- [ ] Is it ok to make `Results` non-final? Can we avoid it?\r\n- [ ] What should we do with `Object.linkingObjects(_:forProperty:)`?"},"comment":{"url":"https://api.github.com/repos/realm/realm-cocoa/issues/comments/208458608","html_url":"https://github.com/realm/realm-cocoa/pull/3419#issuecomment-208458608","issue_url":"https://api.github.com/repos/realm/realm-cocoa/issues/3419","id":208458608,"user":{"login":"jpsim","id":474794,"avatar_url":"https://avatars.githubusercontent.com/u/474794?v=3","gravatar_id":"","url":"https://api.github.com/users/jpsim","html_url":"https://github.com/jpsim","followers_url":"https://api.github.com/users/jpsim/followers","following_url":"https://api.github.com/users/jpsim/following{/other_user}","gists_url":"https://api.github.com/users/jpsim/gists{/gist_id}","starred_url":"https://api.github.com/users/jpsim/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jpsim/subscriptions","organizations_url":"https://api.github.com/users/jpsim/orgs","repos_url":"https://api.github.com/users/jpsim/repos","events_url":"https://api.github.com/users/jpsim/events{/privacy}","received_events_url":"https://api.github.com/users/jpsim/received_events","type":"User","site_admin":false},"created_at":"2016-04-11T17:23:26Z","updated_at":"2016-04-11T17:23:26Z","body":"Another downside to using `Results` for Swift properties is that the constructor would also be available but invalid from other contexts. Putting that in its own type offers stronger context and less chance of accidental auto-complete or confusion IMO.\r\n\r\n> > Have you done any thinking about restricting the number of backlinks to only 1?\r\n>\r\n> I'm skeptical about supporting this at present given that we can't enforce there being only a single backlink to a given object.\r\n\r\nWe could offer a shortcut to an optional first backlink, equivalent to `LinkingObjects(fromType: Person.self, property: \"child\").first`, but I don't see the value there for the same reasons @bdash shared.\r\n\r\n> Objective-C `RLMLinkingObjects` properties are `nil` for standalone objects, but Swift `LinkingObjects` cannot be. How should we reconcile this?\r\n\r\nReturn a `LinkingObjects` backed by an empty RLMResults? I'd actually say that'd be preferable to `nil` in Objective-C too.\r\n\r\n> Do we need to support KVO on linking objects properties in the initial implementation?\r\n\r\nWithout reviewing too deeply, I'd suspect this already works with KVO when tracking top-level results properties like `count`. If it's not too much work to assess what's missing for more complete KVO support, it'd be nice to at least do that before we determine whether or not it's worth the investment. At the very least we should track completing KVO support as a GH issue if we decide to punt on it.\r\n\r\n> Is there a nicer way to declare the properties in Objective-C?\r\n\r\nWe could introduce some sort of `RLMLinkingObjectsDefinition` class in Objective-C which would likely avoid some user issues with remembering the NSDictionary format:\r\n\r\n```objc\r\n@interface RLMLinkingObjectsDefinition : NSObject\r\n@property (nonatomic, copy) NSString *propertyName;\r\n@property (nonatomic, weak) Class linkingClass;\r\n@property (nonatomic, copy) NSString *linkingPropertyName;\r\n@end\r\n```\r\n\r\nNaming alternative could be `RLMBacklinkDefinition` depending on if we want to use that term at all.\r\n\r\n> Is it ok to make `Results` non-final? Can we avoid it?\r\n\r\nWe could avoid it by typaliasing `LinkingObjects` to `Results`, which would be nicer in some ways, worse in others.\r\n\r\n> What should we do with `Object.linkingObjects(_:forProperty:)`?\r\n\r\nI'd vote to deprecate it too."}}