I'm having trouble finding a good tutorial on how to define basic foreign key relationships between models. suppose I have a User model and a Game model..
I would like to define two fields in the Game model - host_id and visitor_id which are mapped via foreign key relationship to the User model. The IDs of the 'host' and 'visitor' fields of the Game class basically define the two players which will engage in a peer-to-peer game... and those fields need to be mapped to actual users of the application as defined in the User model by userID..
Thank you!
Did try this http://guides.rubyonrails.org/association_basics.html?
I think it could be like this:
class User
belongs_to :game
end
class Game
has_one :host_user, :class_name => "User"
has_one :visit_user, :class_name => "User"
end
Related
I want to perform has_one, belongs_to association on a tableless model.
class A < ActiveRecord::Base
has_one: b
end
class B < Tableless
attr_accessor: b
end
I want to know whether this is possible in Rails
Can you define an association on a tableless model? I'm going to answer 'no'. Associations use foreign keys to retrieve associated records and without a table to store that foreign key you cannot retrieve that record.
Documentation about association methods.
Rails app using Devise for user authentication. Started simple, now getting quite complex.
There are 3 kinds of user that will be logging in to the site: Admin, Teacher, Parent. I have a single Devise User model and User.role string for these. There is a Student model (which doesn't log in) and a Lesson model.
These are the relationships I need:
Lesson belongs to one Student
Student has many Lessons
Student has many Teachers
Student belongs to one Parent
Parent has many Students
Teacher has many Students
Basic functionality of the site: Teachers log in and make lessons for their students. Parents log in and see all lessons for their kids (students). Admins log in and can CRUD teachers, parents and students.
I have most of it working but got stumped when I tried to implement 'student has many teachers' and 'parent has many students'. My initial (incorrect) assumptions were that a student only has one teacher and that a parent just has one child at the school.
So it seems that using a User.role string won't suffice for these relationships.
Any advice or general concepts would be greatly appreciated.
Are you just looking for a join table, ie a has_and_belongs_to_many relation?
http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association
As I see it:
class Student
belongs_to :parent
has_and_belongs_to_many :teachers
end
class Parent
has_many :students
end
class Teacher
has_and_belongs_to_many :students
end
There can be multiple ways of solving this, what i understand is that you have solved this much but you have made things bit complex.
you can simply have 1 model `User' and remaining things can be polymorphic.
You can move the common attributes in User and separate the remaining in their corresponding models.
It would be much better if had a look at code.
Thanks
I ended up creating a third model and using has_many :through => to link everything together. I wanted to keep a single Devise user model and use a .role for authorization.
The third model I created was Timeslot, which is essentially where a teacher and student interact. Ideally I would have called it class or session but they're both reserved words.
# timeslot.rb
class Timeslot < ActiveRecord::Base
belongs_to :user
belongs_to :student
end
# user.rb
class User < ActiveRecord::Base
ROLES = %w[admin teacher parent]
has_many :timeslots
has_many :students, through: :timeslots
end
# student.rb
class Student < ActiveRecord::Base
has_many :lessons
has_many :timeslots
has_many :users, through: :timeslots
end
This allows a user with a teacher role to have many students and vice-versa. The Student model has a parent_id column which stores the id of the user with role parent. That part is still a bit clunky but it works fine for now. I'm sure I'll have to refactor to something more elegant if the app has to scale.
I have a small app that allows users to upload recipes and save favourite recipes. I have a separate model called country that has all the countries of the world within it which then allows users to select one from a dropdown.
Initially I had the association as
recipe
has_one :country
country
belongs_to :recipe
After some research the correct association is
recipe
belongs_to :country
country
belongs_to :recipe
The foreign key country_id going within the recipe model.
I'm going to do some more reading but was wondering if someone could explain as to why it is this association and not the first one
I guest you want to build association like this:
country can has many recipe
recipe belongs to one country
If so, you should define association is:
country:
has_many :recipes
recipe:
belongs_to :country
And i think your second association is also incorrect.
When you define belongs_to :country in Recipe model, it means your Recipe table must have a column called country_id. It is a foreign key to Country model.
In the first define association, the Country model will have a column called recipe_id, so, every country just has only one recipe, that's not what you want, right? Why it's not work? Because with one country you have only one record, so one country can have only one recipe, accessed through recipe_id.
With first association, your association is One-to-One (One Country has one Recipe), while you actually want your association is One-to-Many ( One Country has Many Recipe). So it's reason why first association not works (second too).
The main thing you need to remember here is, what model you put a belongs_to association, that model will have a column called 'association name'_id. The different between using has_one and belongs_to only is where you put foreign key and the meaning of association. Check here to clearer.
I'm not sure this is the right association. The belongs_to association is always used in the model that has the foreign key (see here). Having foreign keys in both tables is not a good idea, as far as I can think. Can you explain why you think the last association is correct?
BTW, I think that the correct association is:
country has_many recipes and recipe belongs_to country
I have a basic problem with a has_one and belongs_to association. I have two models: StudentRegistration and User that look like the following:
class StudentRegistration < ActiveRecord::Base
belongs_to :user
end
and
class User < ActiveRecord::Base
has_one student_registration
end
The idea is that a student gets registered and then later a User account can be created. My problem is that I'm storing the foreign key user_id in the student_registration table and I only know this once the user record has been created. When the user account gets created I need to update the student_registration table adding the new user id.
Is it the case that I just have this the wrong way around or should Rails handle this automatically?
You have setup your associations the correct way, but I guess the implementation is wrong.
No problems, just go through this link and you'd be good to go.
Nested-model-form-part-1 - Railscasts
A phone has many messages.
An email address has many messages.
A message either belongs to a phone, email, or neither. The belongs_to association is optional.
The following associations seem to work fine for these relationships:
Phone model has_many :messages
Email model has_many :messages
Message model does NOT have belongs_to :phones, :email
Is this okay or is there some proper way to specify a "can_belong_to" relationship?
It is completely correct unidirectional relation. Using both is sometimes called "curcular dependency" by some purists and may cause problems when using validates_associated.
From the other side using only has_many :messages may be not enough when you want retrieve phone information from one message. Generally it is matter of convenience.
The model with the belongs_to associations holds the foreign keys (e.g. messages table would have phone_id and email_id columns).
The belongs_to association combined with has_many lets you easily access associated records:
phone.messages
message.phone
So without the belongs_to and FK columns, the has_many association isn't very useful.
It seems like in this case you may want a many-to-many relationship such as has_and_belongs_to_many as a message can have many recipients.