NEW: My new book Pro SwiftUI is out now – level up your SwiftUI skills today! >>

SOLVED: Day 61 help with creating a relationship in my data model

Forums > 100 Days of SwiftUI

I'm trying to work through the day 61 challenge of adding CoreData functionality to the previous day's challenge of building the FriendFace app.

I'm just a bit confused about how to set up the relationship between the CachedUser and CachedFriend Entities in the data model for this project.

Each User can have many Friends, that part is clear.

However, the inverse relationship is a bit trickier to think about. Each Friend represents (shares a name and id with) one User in the data. But, each Friend can also be linked to (can be a friend of) many different Users in the data.

Is this a many to many, many to one, or one to many type of relationship?

Or, are there two separate relationships between these entities happening here?

  1. A one to one relationship between User.id and Friend.id
  2. A many to many relationship between User.friends and Friend.users (even though Friend.users doesn't exist as a property in the data)

I'm not sure.

For clarity, for people who may not have looked at this project in a while, this is the way that the structs were set up before trying to add CoreData to the project. So, the User has a property named friends of type [Friend]. The Friend struct only has 2 properties, id and name. The actual data is being downloaded from this link

struct User: Identifiable, Codable {
    struct Friend: Identifiable, Codable {
        let id: UUID
        let name: String
    }

    let id: UUID
    let isActive: Bool
    let name: String
    let age: Int
    let company: String
    let email: String
    let address: String
    let about: String
    let registered: Date
    let tags: [String]
    let friends: [Friend]

    var formattedRegistrationDate: String {
        registered.formatted(date: .abbreviated, time: .omitted)
    }
}

   

I think the reason why this is so difficult to wrap my ahead around is just that this data model doesn't make any sense to me.

Why would we need to have two separate entities when one of the entities is just a copy of two of the properties from the other entity?

   

Well, I ended up getting the project to work anyway. But I'm still not 100% sure if I set up the relationship the correct way. If anyone is interested in how I did it, I'll tell you.

I created an Entity called CachedUser with properties for id, isActive, age, company, name, email, address, about, registered, and tags. Then I created a "to many" relationship to "CachedFriend" on the entity and named it friends.

I also created an Entity called CachedFriend with properties for id and name. Then I gave it a "to many" relationship to "CachedUser" named it friendOf.

This seems to work, but It just seems strange to me to have to add a relationship on the CachedFriend entity with a name that doesn't exist in the data, and that is never used anywhere in my code. So, maybe there is a more correct way to do it. But, I guess I'll just leave it this way for now.

   

You are quite right that in designing a relational database, it does not make sense to duplicate the name property in both User and Friend. Generally, if you find yourself duplicating the same information in two entities, you need to reorganize what properties are in what entities and how to relate the entities.

The original non Core Data design would be more efficient by eliminating the Friend struct and replacing the friends property of User with a property called friendIDs, whose type is a Set of ids of that user's friends.

To implement the corresponding efficient design in Core Data, with only a single entity called User, you would define a user's friends by a "self relationship" (or "self join"). Specifically, the friends property of User would have a One-To-Many relationship to the same User entity!

Incidentally, in Core Data you normally don’t need an id property. Core Data creates its own id property for each entity behind the scenes. Consequently, all entities are Identifiable, so you don’t need an explicitly defined id in a ForEach, for example.

1      

@Bnerd  

Can you please share how you save the friends array in CoreData?

   

You don't exactly store the friends array as an array in the data model. But you create a relationship between your two existing entities, and name it friends.

When you create a relationship between two entities in your data model, the relationship basically gets created as a new table in your database, which can hold data about many instances of an entity in one place. So, the relationship itself acts as the array.

The instructions in my previous comment describe how I created the relationship. But @bobstern provided a solution for how to solve this problem with a more efficient and less redundant data model.

   

Hacking with Swift is sponsored by MadMachine

SPONSORED Want to try Swift on microcontrollers? MadMachine provides ways to interact with the physical world in a Swift way. Join us and have fun!

Get it now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.