CoreData and intermediates - ios

I am a little confused as to how to model this in CoreData? It's fairly simple concept, I want to be able to track how long a player has played in a certain game. So I have the following objects (simplified for brevity):
Player
- name
- currentGamePlayedTime
(1:1 relationship to Team)
Team
- name
(1:1 relationship with Player)
(1:Many relationship with Game
Game
- date
(Many:1 relationship with Team)
I want to be able to look back at a player's playing time in a certain game, or see the whole team's playing time in a game. But I'm unsure how to model that. Using an SQL approach i'd have an intermediate table (shown below), and have 15 entries or so, one for each player who played in the game and the corresponding time they played.
GameRecord
- GameID
- PlayerID
- TimePlayed
My app is able to workout how much a player has played in the current game and store it on the Player object currently, but I don't know the long term solution to saving that playing time to a corresponding Game object - whether that's directly on the object or via an intermediate.
I've seen that some people do use intermediates. But I've also read that using SQL practices isn't the write way to think about the object graph. So just wanted an idea of how something like this should be modeled.

Using intermediate entities to model many-many relationships is perfectly legitimate. Indeed, it is necessary in situations such as yours where you want to store information about the relationship itself.
There is an example of this in the Core Data Programming Guide, in the section entitled "Modeling a relationship based on its semantics" (whatever that means). Their example is a reflexive relationship, but the argument applies to any many-many relationship.

Related

Core Data Schema Design

I'm trying to write an iOS application that tracks how much weight your lifting at the gym but I'm struggling to create my Core Data schema. At the moment i have an Exercise Entity that stores info about a specific exercise (e.g. Bicep Curl) and i have a workout Entity that just has a name & image. The workout entity has a many to many relationship with the exercise entity. what i need to incorporate is 'session' functionality - the ability for a user to complete a workout and store the weights he/she lifted in a particular workout. E.g. i want to say that i completed my 'Leg Day' workout and lifted these weights for each exercise. So my Core Data looks like this at the moment.
schema
How would i go about storing the session data? I feel that the session must have a one to one relationship with a workout but that doesn't let me add results for each exercise in the workout... I also think i might need a dictionary to store the weights for each exercise.
Any help would be greatly appreciated as i have never really learnt about databases before.
Thanks
EDIT: Ive changed my schema to look like this
schema2
So, regarding your schema2, in database design it is typically bad practice to have relationships that form a "circle". Also, if an entity only has a single attribute, it could be reduced to an attribute of its parent.
I would probably approach your design a bit differently.
You should split your exercise entity into Exercise and Exercise_History or something similar. Then you would remove any relationship between Session and Workout and have a one to many between Session and Exercise_History.
Also, if Lift only has a single attribute, it probably shouldn't be its own entity.
If you approach it like that, you should get the desired relationships and functionality.

Core Data Attribute dependent on Relationship

I am trying to add an ordered array object to my CoreData setup, I know that you cannot do this as an NSSet is unordered, and I know that the simplest way to achieve this is to add an attribute to the entities within the set which can be used to order the set once you fetch it. However this is where I run into a problem with my setup, it's a little bit complicated:
I have entitities: CricketPlayer and CricketTeam... The user can create a CricketTeam object with an ordered array of CricketPlayer's which represents the batting lineup. When I next retrieve this list I want the lineup to be presented to the user in the same order in which they set it when creating a team... The only problem is within my app - the same goes in real life! - a player can play for more than one team so if I set an attribute on CricketPlayer say: batterNumber although this will enable me to re-create the batting lineup, if I then create another team with the same player in and bat him at a different position I will have ruined the batting lineup for the original team!
What I am therefore looking to do is create a 'pseudo-relationship' which is not a relationship to another CoreData entity but an attribute on an entity which depends on which entity it is being used within... so in my case I want an attribute on a CricketPlayer entity which represents that players batting number in a particular CricketTeam if that makes any sense at all!
You need a few more entities. I assume a player can play for a team more than once i.e. in more than 1 match, in a different order in the batting lineup. So you need a match entity which links CricketTeams, and record the batting order of the teams for that specific match.
Match
HomeTeamID
AwayTeamID
Team
TeamID
TeamName
Player
PlayerID
PlayerName
PlayerTeam
PlayerID
TeamID
MatchBattingOrder
MatchID
PlayerID
TeamID
BattingOrder
This is very simplistic! This is a data modelling issue

How to have repeated items in an Ordered To-Many relationship?

In Core Data of Xcode 4.3.2, an Ordered To-Many relationship is modelled with NSOrderedSet. It works well until I found the need to have repeated items in the relationship; it should really be modelled in a NSArray.
For example, in a music app, I have the following songs: SongA, SongB, SongC ,
I may want a party play list where people insert songs in any order and could be repeated. The list may look something like:
[SongC, SongC, SongA, SongC]
The way Core Data currently works, the list would become:
[SongC, SongA]
I.e., all repeated items are dropped, as it is modelled with sets.
So, coming back to my question: what is a good way to model repeated items in order in a relationship in Core Data?
Relationships are sets (and ordered relationships are ordered sets, but still sets); sets by definition contain unique objects. So you can't put duplicate objects into a relationship either way.
Whether you use the ordered-relation feature or not, you'll want to go back to the abstract ER model to find another way to turn your conceptual relationships into a Core Data model... it might help to think about how you'd do it in a plain SQL (or SQL-like) database and then come back to what Core Data does beyond SQL.
It sounds like you're making something akin to iTunes playlists, no? A model that might work for that would go something like:
Playlist <--->> PlaylistEntry
PlaylistEntry <<---> Song
The PlaylistEntry entity represents one instance of a Song's inclusion in one Playlist. You can have multiple PlaylistEntrys that reference the same Song in a single Playlist, and you can add other attributes to the PlaylistEntry to keep track of other things (like song order, if you're not using an ordered relationship). As a bonus, you can use that to add other features if you like -- say, to make a playlist that plays three different snippets out of one long track.
As rickster said, relationships as managed by Core Data uniquely associate entities between them. Even if Lion's Core Data (is supposed to) supports ordered relationships (supposed to, because in practice it won't work, the feature is buggy, barely usable), they still are relationships that follow the relational database model.
And so you have to manage the association by yourself, and you most certainly have to manage the ordered part of the association by yourself too.
Score <->> ScoreSong
ScoreSong <<-> Song
With ScoreSong having the following properties:
ScoreSong:
- score: -> Score
- song: -> Song
- order: integer, indexed
Then you have to use a Fetch Request with a sort descriptor for the key order, which will return an ordered NSArray of ScoreSong. You can ask the fetch request to prefetch the songs, then you can create the songs array, still properly ordered, with a single call to valueForKey: #"song".
Of course you have to create different ScoreSong for a single Song when you need to include than song more than once in your Score. That's the whole point of the added indirection.

Howto "virtually" create and save an attribute of a separate model in rails

The title may appear as if I am asking howto access/find/update an attribute of a related/nested model but this is not the case and unfortunately this is the best title I could figure out.
I would like to build a soccer management game with ruby on rails, where routine total_attack_value and total_defense_values are matched etc. I don't plan to make the simulation too deep like in here and here, such as calculating and matching separate corner_attack or side_attack values but seriously intend to include the goalkeeper's skill in total_defense_value.
To clarify, the total_attack_value is going to be calculated as "total_shooting_value x total_pass_value x total_possess_value x/+ Rand() etc" and all of these ..._values are going to be calculated inside the Team model but the total_defense_value should have "goalkeeper_skill_value" which is going to be the skill of the player selected as the goalkeeper by the user for the coming match, as I planned.
I cannot think of anything else than saving and retrieving which player is put into goalkeeper position by the user using virtual attributes, since the user is going to schedule the match for a future time and the goalkeeper selection should persist until then. In this case I'm going to create a Player_Position model and an association model belonging to both Position and Player and an assign_positions function in Player model etc. However this is exactly what I am trying to avoid, code- and complexity-wise being the same as to offer the user the possibility to drag&drop players to positions separately as seen in some games like soccermanager and goalunited.
Does rails offer any simple/ready solution to this problem as it does to simple CRUD operations, like an attribute or STI?
I'm not sure if I completely understand what you are trying to achieve but the next version of Rails, 3.2, has simple Key Value Store functionality that you may be able to use. The release candidate is already out so you would be able to try it out to see if it met your needs.
A short note on the functionality was included in the latest release notes.

Rails Foreign key setup question

I'm just (re)starting playing around with Rails and I'm making a little card game app. I cannot seem to figure out my Foreign Key setups.
Say I have 4 objects:
- Game
- Player
- Hand
- Card
A Game has many Players, which have many Hands which have many Cards. But the cards are also independent of a Hand, Player and Game.
For example, I have 6 Cards in my database (1 to 6). It is possible that Card 3 could be in 2 Players Hands in the same Game.
How can I set up my keys for this? Should I just create another object for "CardInHand" to simplify it?
The relationship between cards and hands is the classic Has And Belongs To Many (HABTM). When you have a HABTM relationship, there needs to be a table to manage the pairings (hands_cards, say, with just pairs of ids in it) but there need not be a corresponding model.
(Note that you'll need to create a migration to generate the hands_cards table yourself; it won't be created automatically.)
You do have the option, as you say, to create a separate model to represent a card being in a hand -- this is a has_many :through relationship -- but I would only do that if there's a special reason to model that relationship as a concrete object.
The standard Best Practice for Rails is not to use foreign keys in the db, but to use validations on the model to ensure data correctness.
As the other answer explains what you'll want to set that up.

Resources