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.
Related
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.
first week playing with rails and I'm a bit stuck on this active record relationship
I have 3 tables right now, Events, Fights and Fighters. Every fight belongs to an event and fighters can have many fights. I want to be able to store information in the fights table such as the winner, how the fight was won, the referee etc.
I've been doing some research and I think I'll need a bi-directional self-referential has many through relationship for the fights. Does this require 2 entries in the through table? If so, how can I query the fights while viewing an event without 2 records for each fight showing?
What would be the best way to store the winner if I want to show the fighters record on the fighters page? Have a winner_id and a loser_id in the table? This gets confusing when there can be draws and no contests.
There can also be fights with no outcome because they haven't happened yet. I'm thinking of using a seperate table for those.
Any suggestions are greatly appreciated!
Cheers
I suggest adding a few more tables:
Participants
could support more than two fighters in a match (not sure of your domain, but this could be useful for tag-team wrestling)
fight_id - foreign key to fight (belongs_to)
fighter_id - foreign key to fight (belongs_to)
Decision
The decision could have alot of information like type = "KO", "TKO", etc. Other info like Judges voting. Draws and no-decision would not go here
fight_id - foreign key to fight (belongs_to)
type
winner_id
loser_id
dt - datetime for when the decision was reached
And edit fights to contain a field on status:
Fights
status - (decision, no-decision, draw, cancelled, postponed, etc)
I have a user and a merchant that have a relationship. I need to store information about the relationship, so I am using => through user_merchant_relations.
1) Is my naming convention incorrect? I've read some answers that indicate it might have to be merchant_user
2) Should I force the "join" / "through" table to NOT have a separate ID (e.g. only have the two foreign keys)?
3) In the relation table I reference a program_id. A User-Merchant relation can only have one Program ... but Programs will belong to many User-Merchant relations ... what is the correct way to handle this?
Thank you very much.
1 - The convention is that the models should be ordered alphabetically, so the name should be merchant_user
2 - It seems that with the logic you explained there will be no merchant_user with the same merchant and user at the same time, so you can skip the id. Remember to properly create the validations.
3 - It seems that Program has many MerchantUser and MerchantUser belongs_to Program
I've read so many Rails books/tutorials, but when it comes time to actually make the app, I keep tripping over myself, so I'm trying this little exercise to help me get it better.
I have an app with 3 classes (Link, Url, Visit) that have associations defined between them, such as has_one, belongs_to etc. This allows me to call methods like Link.url
If I were to convert this into an app with a single model, is it possible to create the convenience methods (such as Link.url) even though there are no relationships between models, because there is only one model.
This might not be the 'Rails way' but if you answer this question it'll help me get it more.
I guess another way to ask this is, do the Rails associations only exist because the tab
Thanks
Models exist to represent tables in a database. If you have 3 different conceptual objects, then you need 3 different models. Keeping those objects separate and in different tables/models is essential to good programming in any language. The relations are there to help you understand the correlation of each object to the others.
If you think all of data from each of the models can be represented in one table sensibly, then combine them in to one model with a name that encompasses all of the data. If you choose this option, you'll use columns for that one table which represent each of the pieces of data you need. Those column names come free in the model when you create the migration. A table with a column named "url" on a model named "Hit" could be used like this:
Hit.first.url
I have this app I am writing in Rails 3.1, I am wondering the best way to model this.
Would it be best if I created a model called "Movie" with a "title" and then create a new model for each "movie asset" such as "poster, trailer, screener" etc and relate it to the "Movie" by associations? Or would it be best if I just created this as one and do-away with the of associations of each asset to "Movie"?
My assumption is to just make it as one as it will remove all the overhead of the FK's and joins to get retrieve the data related to the movie but I am looking for opinions/suggestions. Thanks
There can be three types of attributes(columns) for movies.
Which have exactly one value, and are present in every movie e.g. title, year, official trailer etc.
Keep them in the movie table.
Which have exactly one value, but are present in few of the movies e.g. total Academy Awards.
Keep them in separate table, and use has_one+belongs_to association.
Which have multiple values e.g. trailers
Keep them in separate table, and use has_many+belongs_to association.
More suggestions:
For many key-value attributes, it is easier to use one json/yaml column using serialize instead of creating one column for each key.
Do not store images in DB, keep them in file-system or cloud storage.
You can create your models in the order you want since you have to fill in both models to create a unique association (such as belongs_to and has_many) so I think it doesn't really matter !