protasm
protasm

Reputation: 1297

Core Data: To-Many Relationships with Repeat Values

In a mileage-tracking app I am developing, the concepts include "Places," "Legs," and "Routes." Essentially, a Route is a collection of connected Legs, where each Leg is simply a straight line between two Places (with an associated distance).

I am having a problem modeling the Route-Leg relationship in Core Data because a Route may include the same Leg twice or more. For example, a person could travel Home to Office, Office to Worksite, Worksite to Home, Home to Office, and Office to Home as a single, contiguous path of travel on a given day. In that case, the "Home-to-Office" Leg is contained twice in the Route. But Core Data creates the To-Many relationship in a NSManagedObject subclass as an instance of NSOrderedSet, which does not permit duplicate Legs.

Is there a way I can create a relationship between the two Core Data-backed objects (Route and Leg) that allows multiple occurrences of the same Leg in a single Route? I am developing my app in Swift, so any Swift-specific suggestions would be appreciated.

Thank you.

Upvotes: 0

Views: 73

Answers (2)

pbasdf
pbasdf

Reputation: 21536

Presumably you currently have a many-many relationship between Leg and Route. One solution is to replace this many-many relationship with an intermediate entity (say RouteLegDetails) which has to-one relationships with Leg and Route. Each Route can have many RouteLegDetails and likewise each Leg can have many RouteLegDetails. In the data model editor, it might look something like this:

enter image description here

This way, if you have a Leg that is traversed twice (or more) on the same Route, each instance is represented by a different RouteLegDetails: which overcomes the restriction on duplicates in the legDetails ordered set.

This will complicate your code slightly: when you want to add a Leg to a Route, you will have to create a RouteLegDetails object, and add it to both the legDetails relationship on the Route and the routeDetails relationship on the Leg. Conversely to remove a Leg from a Route, you will need to delete the corresponding RouteLegDetails object.

Upvotes: 2

user3847320
user3847320

Reputation: 822

It seems like there might be an opportunity to improve your model object to solve this challenge. As I understand it now, you will not be able to fully define a route based on what you are currently modelling. How could you fully define a route from its constituent legs? Since the relationship is inherently unordered there is no way to build a route from the legs by just examining the relationship as you will not know in which order the legs occur.

One option is to store an order property with your leg object. A leg with the same start and end point, but a different order would be a distinct object.

A second and possibly cleaner approach would be to store the order of the legs in the route object (perhaps as a list of leg IDs leg 1 -> leg 3 -> leg 4 -> leg 1 -> leg 2). The legs relationship would get you all legs to build the route, the leg order property stored in the route object would allow you to construct the route from its legs, even if you use the same one twice. An array is the obvious way to store the order of the legs by ID, however an array is not a supported core data type, you may want to consider storing the order of the leg IDs as a string you can parse or a transformable attribute. See Transformable Attribute

Upvotes: 1

Related Questions