In my rails app, I have three tables: forms,languages and levels.
My forms table holds info about curricula people submit.
It has various columns regarding the submitter personal info, and one of them is their foreign language knowledge level.
My languages table holds the languages that should be present in the curriculum form, and it has the id,name,created_at and updated_at columns.
My levels table holds the language knowledge levels, right now it has only Basic, Medium and Advanced, and it has the id,name,created_at and updated_at columns.
I was able to relate my languages table and my levels table using the following code:
#app/models/level.rb
class Level < ActiveRecord::Base
has_and_belongs_to_many :languages
end
#app/models/language.rb
class Language < ActiveRecord::Base
has_and_belongs_to_many :levels
end
Now, a fourth table exists in my database to relate these two tables, the languages_levels table, which has nothing else but the language_id and the level_id columns.
Is there a way, using Formtastic, to relate this languages_levels table to my forms table in a way that for every language recorded in the languages table, a set of radio button inputs present in the levels table to appear?
For what you described, using the bridge table (using the language_lavels table with has_and_belongs_to_many) seems to be a wrong approach. You just need three-way one-to-many relations.
In other words, you should create a model, say LanguageLevel, which belongs to Form, Language, and Level. Then you can populate LanguageLevel for each Language for each Form.
check this screencasts they might point you in the right direction:
http://railscasts.com/episodes/47-two-many-to-many
http://railscasts.com/episodes/185-formtastic-part-2
Related
Title is the question. When should a relationship in an ER diagram be given its own table in a RDBMS? For instance, one mail courier(with attributes eid and surname) can deliver a number of packages but a package(attributes,pid, sent_By, going_to) can only have one mail courier. Would it make sense to make a table for the relationship called delivers(with an attribute of the time that the package was delivered)? or should the eid of the mail_courier and time_delivered from the deliver relationship be added to the package entity? Also, what would be an example when you would not want to add the attributes to the package entity?
I think what you are trying is to create a one-to-many relationship between two entities. And for that, there is no need to create a separate table; as you mentioned in your question, just add those two attributes to the package table.
Where you would need to create a separate table is when you want to achieve many-to-many relationship between two entities. For example, take twitter's followers. One user can have many followers and a follower can follow many users. You can't do that the relational way without creating a new table with just those two columns.
I am designing a database that contains JOBSEEKERS who can be matched to VACANCIES. I am looking for an effecient and good way to store the common attributes between the 2 (There's a lot). For example a JOBSEEKER has skills and a VACANCY has required skills; or a JOBSEEKER has a salary requirement and a VACANCY has a salary offer.
Right now I am considering two options:
Storing all the attributes or each table in their own table.
Creating another table that contains the common attributes. Each row would represent the attributes for either a VACANCY or JOBSEEKER. I would then link each record to either a VACANCY or a JOBSEEKER.
Which way should is the correct way of going about this? Other suggestions are also welcome.
JobSeeker and Vacancy are two separate entities. In most cases, you would store the values in separate tables with separate columns. Although they have overlapping attributes, they have many attributes that are not common.
The, use application code logic (often implemented in SQL) to match between the two.
For something like skills, you actually want junction tables: JobseekerSkills and VacancySkills to list each of the skills. These would, in turn, reference another table Skills to ensure that the skills are common between the two entities.
Like the title says, I want to move from a one-to-one relationship into a many-to-many relationship in my rails 3 app.
I'm fairly good with rails now but I lack a good understanding of databases and migrations.
Currently, I have a Project and User model. A Project belongs_to a User and a User has_many Projects.
I want to move into a situation where a project can have many users collaborating on it at once.
I'm pretty sure I need to set up a has_many :through type of relationship, but I am also curious as to how I can migrate all of my existing projects and users into this type of system.
Thanks!
You need another table that links the two tables together. This is how to support many to many relationships.
e.g. Say you have two tables like this:
Projects
----------
projectid
{other columns}
Users
-------
userid
{other columns}
The new table will look something like this:
New Table
Projects_Users
--------------
projectid
userid
Now you can add another user to a project by simply adding the userid and projectid to
the Projects_Users table. Similarly you will be able to add several users to the one project in the same table.
The primary key on that table is the composite key projectid & userid.
Right, I have the relationship set up now. How do I migrate all of my existing projects and users into this new format table ?
Well, it depends on how you have set the tables up now; how the two existing relations are implemented; where the ProjectUser data is sitting in the old table. Post your DDL. You should be able to simply INSERT ProjectUser SELECT FROM .... We need to complete that FROM.
Also the number of rows is relevant; if it is large, you may have to break it into batches.
I am starting a new Project for a website based on "Talents" - for example:
Models
Actors
Singers
Dancers
Musicians
The way I propose to do this is that each of these talents will have its own table and include a user_id field to map the record to a specific user.
Any user who signs up on the website can create a profile for one or more of these talents. A talent can have sub-talents, for example an actor can be a tv actor or a theatre actor or a voiceover actor.
So for example I have User A - he is a Model (Catwalk Model) and an Actor (TV actor, Theatre actor, Voiceover actor).
My questions are:
Do I need to create separate tables to store sub-talents of this user?
How should I perform the lookups of the top-level talents for this user? I.e. in the user table should there be fields for the ID of each talent? Or should I perform a lookup in each top-level talent table to see if that user_id exists in there?
Anything else I should be aware of?
before answering your questions... i think that user_id should not be in the Talents table... the main idea here is that "for 1 talent you have many users, and for one user you have multiple talent".. so the relation should be NxN, you'll need an intermediary table
see: many to many
now
Do I need to create seperate tables to store sub-talents of this
user?
if you want to do something dynamic (add or remove subtalents) you can use a recursive relationship. That is a table that is related to itself
TABLE TALENT
-------------
id PK
label
parent_id PK FK (a foreign key to table Talent)
see : recursive associations
How should I perform the lookups of the top-level talents for this
user? I.e. in the user table should
there be fields for the ID of each
talent? Or should I perform a lookup
in each top-level talent table to see
if that user_id exists in there?
if you're using the model before, it could be a nightmare to make queries, because your table Talents is now a TREE that can contain multiple levels.. you might want to restrict yourself to a certain number of levels that you want in your Talent's table i guess two is enough.. that way your queries will be easier
Anything else I should be aware of?
when using recursive relations... the foreign key should alow nulls because the top levels talents wont have a parent_id...
Good luck! :)
EDIT: ok.. i've created the model.. to explain it better
Edit Second model (in the shape of a Christmas tree =D ) Note that the relation between Model & Talent and Actor & Talent is a 1x1 relation, there are different ways to do that (the same link on the comments)
to find if user has talents.. join the three tables on the query =)
hope this helps
You should have one table that has everything about the user (name, dob, any other information about the user). You should have one table that has everything about talents (id, talentName, TopLevelTalentID (to store the "sub" talents put a reference to the "Parent" talent)). You should have a third table for the many to many relationship between users and talents: UserTalents which stores the UserID and the TalentID.
Here's an article that explains how to get to 3rd NF:
http://www.deeptraining.com/litwin/dbdesign/FundamentalsOfRelationalDatabaseDesign.aspx
This is a good question to show some of the differences and similarities between object oriented thinking and relational modelling.
First of all there are no strict rules regarding creating the tables, it depends on the problem space you are trying to model (however, having a field for each of the tables is not necessary at all and constitutes a design fault - mainly because it is inflexible and hard to query).
For example perfectly acceptable design in this case is to have tables
Names (Name, Email, Bio)
Talents (TalentType references TalentTypes, Email references Names)
TalentTypes (TalentType, Description, Parent references TalentTypes)
The above design would allow you to have hierarchical TalentTypes and also to keep track which names have which talents, you would have a single table from which you could get all names (to avoid registering duplicates), you have a single table from which you could get a list of talents and you can add new talent types and/or subtypes easily.
If you really need to store some special fileds on each of the talent types you can still add these as tables that reference general talents table.
As an illustration
Models (Email references Talents, ModelingSalary) -- with a check constraint that talents contain a record with modelling talent type
Do notice that this is only an illustration, it might be sensible to have Salary in the Talents table and not to have tables for specific talents.
If you do end up with tables for specific talents in a sense you can look at Talents table as sort of a class from which a particular talent or sub-talent inherits properties.
ok sorry for the incorrect answer.. this is a different approach.
The way i see it, a user can have multiple occupations (Actor, Model, Musician, etc.) Usually what i do is think in objects first then translate it into tables. In P.O.O. you'd have a class User and subclasses Actor, Model, etc. each one of them could also have subclasses like TvActor, VoiceOverActor... in a DB you'd have a table for each talent and subtalent, all of them share the same primary key (the id of the user) so if the user 4 is and Actor and a Model, you would have one registry on the Actor's Table and another on the Model Table, both with id=4
As you can see, storing is easy.. the complicated part is to retrieve the info. That's because databases dont have the notion of inheritance (i think mysql has but i haven't tried it).. so if you want to now the subclases of the user 4, i see three options:
multiple SELECTs for each talent and subtalent table that you have, asking if their id is 4.
SELECT * FROM Actor WHERE id=4;SELECT * FROM TvActor WHERE id=4;
Make a big query joining all talent and subtalent table on a left join
SELECT * from User LEFT JOIN Actor ON User.id=Actor.id LEFT JOIN TvActor ON User.id=TvActor.id LEFT JOIN... WHERE User.id=4;
create a Talents table in a NxN relation with User to store a reference of each talent and subtalents that the User has, so you wont have to ask all of the tables. You'd have to make a query on the Talents table to find out what tables you'll need to ask on a second query.
Each one of these three options have their pros and cons.. maybe there's another one =)
Good Luck
PS: ahh i found another option here or maybe it's just the second option improved
Though my problem is specifically in Ruby on Rails, I'm also asking generally: I have a users table and want to designate some users to be students and others to be teachers. What is the best way to design the schema in this case?
Edit:
Though I originally accepted vonconrad's answer--it fits the original criteria--I have to reopen and adjust the question based on feedback from nhnb.
What should be done if students and/or teachers require additional (unique) attributes?
This greatly depends on how many the different attributes between the teacher and student there'll be as well as how often new unique attributes will be added or removed. If the case is that they will differ a lot, you have two choses:
Make two models, one for Student and one for Teacher and use ruby include to share any logic between the two models. Any associations that associate with a user, you would use a polymorphic association (has_many :user, :polymorphic => true)
Put the attributes in another table. For example: you'll have the users table and a user_attributes table. users would have id, user_type, username, etc. and user_attributes would have id, user_id, attribute_name, value.
If, however, your different attributes between the two users are few and pretty rock solid, you should just consider using Single Table Inheritance.
Good luck!
In this case, I'd simply go with a single boolean column called teacher. If true, the user is a teacher. If false, it's a student. No need to create another model.
If you want more than two roles (say, student, teacher, administrator, janitor(?)), you can add another model called UserGroup. You'll also have to create a column in the users table called user_group_id. In the new model, you have a single row for each of the roles. Then, you specify the following relationships:
class User < ActiveRecord::Base
belongs_to :user_group
end
class UserGroup < ActiveRecord::Base
has_many :users
end
This will allow you to assign each user to a specific group.