I have 4 models in my rails app:
Classroom / Teacher / Pupil / Assignment
I need to have a:
n*n relationship between Classroom and Teacher
n*n relationship between Teacher and Pupil
For those two relations, that's ok as I'll create 2 migrations for the has_and_belongs_to_many .
For the Assignments model, I need to have it linked with the 3 previous models:
Assignments table should be like:
- id
- label
- classroom_id
- teacher_id
- pupil_id
Is the following the best approach to modelize this last relationship ?
class Assignment < ActiveRecord::Base
belongs_to: classroom
belongs_to: teacher
belongs_to: pupil
end
class classroom < ActiveRecord::Base
has_many: assignments
end
class teacher < ActiveRecord::Base
has_many: assignments
end
class pupils < ActiveRecord::Base
has_many: assignments
end
Consider polymorphic association http://guides.rubyonrails.org/association_basics.html#polymorphic-associations
class Assignment < ActiveRecord::Base
belongs_to: assignable, :polymorphic => true
end
class Classroom < ActiveRecord::Base
has_many :assignment, :as => :assignable
end
Related
I have a model A which belongs to my User model. I also have a model B, which belongs to my B model and also my User model (those are two different users, like doctor and patient). What I would like to do is some query like this:
B.joins(:user, {a: :user}).where("patient.name = 'some condition' or doctor.name='some other condition'")
The point here is: how can I specify that the users.name I'm querying is the one which is associated to A or B model?
Any help will be appreciated, thanks!
Perhaps something like this could work? (I haven't tested the code)
class User < ApplicationRecord
has_many :doctors
has_many :patients, through: :doctors
end
class Doctor < ApplicationRecord
belongs_to :user
has_many :patients
end
class Patient < ApplicationRecord
belongs_to :doctor
belongs_to :user
end
Patient.joins(user: {doctors: :user}).where("patient.name = 'some condition' or doctor.name='some other condition'")
Hope this helps!
You can create new classes named Patient and Doctor that inherit from User, then refer to users as patients and doctors instead of generic users.
class Doctor < User
has_many :a
end
class Patient < User
has_many :b
end
This is Single Table Inheritance:
https://api.rubyonrails.org/classes/ActiveRecord/Inheritance.html
What is the correct way to create active record relationships for a scenario where-
One instance of a Model A can belong to multiple of instances of two other models, Model B and Model C at the same time.
Model B can only have one Model A.
Model C can have many Model A's.
An example is a job board where an employer is hiring for one position and candidate is applying and has many previous positions. I want both the candidate and employer positions to be from the same model.
Position Mode (Model A)
can belong to both employers and candidates at the same time
Employer Model (Model B)
has_one position
Candidate Model (Model C)
has_many positions
Here's one way of accomplishing what you described in the question:
class Position < ActiveRecord::Base
belongs_to :candidate
belongs_to :employer
end
class Employer < ActiveRecord::Base
has_many :positions
end
class Candidate < ActiveRecord::Base
has_many :positions
ens
Note that a position can only belong to one employer and one candidate at a time; this is kind of nonsensical if you are creating a job board - the relationship between position and employer is probably correct, but candidates might have many applications, and an application would belong_to a position, while a position has_many applications. Or possibly also "favorites" so candidates could keep track of a list of positions to apply to.
The "theoretical" example that you started with:
One instance of a Model A can belong to multiple of instances of two other models, Model B and Model C at the same time.
Model B can only have one Model A.
Model C can have many Model A's.
Code:
class ModelA < ActiveRecord::Base
has_many :model_bs
has_many :model_c_relationships # join table!
has_many :model_cs, through: :model_c_relationships
end
class ModelB < ActiveRecord::Base
belongs_to :model_a
end
class ModelCRelationship < ActiveRecord::Base
belongs_to :model_a
belongs_to :model_c
end
class ModelC < ActiveRecord::Base
has_many :model_c_relationships
has_many :model_as, through: :model_c_relationships
end
If there is a situation where one type of object can belong to one other object, but that other object can be one of several types, then it might need a polymorphic association. For example, StackOverflow allows you to comment on both questions and answers. A comment can only belong to one comment-able parent object, therefore the code might look like this:
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
end
class Question < ActiveRecord::Base
has_many :comments, as: :commentable
has_many :answers
end
class Answer < ActiveRecord::Base
belongs_to :question
has_many :comments, as: :commentable
end
I have User, Teacher and ClassRomm model using STI as following
class User < ApplicationRecord
end
class Teacher < User
has_many :class_rooms
end
class Student < User
has_many_and_belongs_to :class_rooms
end
class ClassRoom < ApplicationRecord
belongs_to :teachers
has_many_and_belongs_to :students
end
my question how can i create migration for all relationships between user,teacher,Student and classRooms ?
for example should class_rooms has forignKey column for instructor_id or user_id
first of all
in ClassRoom association should be singular belongs_to :teacher, without s
also ClassRoom mast have column teacher_id, than create "third" table with name ClassRoomsStudents for has_many_and_belongs_to association
and it should works
In my app I have 2 classes. User and Classroom. I use the user class as a student as well.
I'm trying to achieve a result where:
A classroom belongs to a user.
A user has many classrooms.
A classroom has one student through the user class.
A student can be associated to many classrooms.
To try and explain further. I have a classroom and the user is the creator of the classroom. When someone joins they are a student of the classroom and I only want there to be one student and one creator.
I want a student to be attached to lots of different classrooms and I want the classrooms to all belong to one user.
My current code for the two classes looks like this:
class User < ActiveRecord::Base
has_many :classrooms
end
class Classroom < ActiveRecord::Base
belongs_to :user
has_one :student, :class_name => "User"
end
Any advice is much appreciated. Thanks!
I think what you are trying to achieve is:
class User < ActiveRecord::Base
has_many :classroom_users
has_many :classrooms, through: :classroom_users
end
class ClassroomUser < ActiveRecord::Base
belongs_to :classroom
belongs_to :user
end
class Classroom < ActiveRecord::Base
has_many :classroom_users
has_many :users, through: :classroom_users
end
class Post < ActiveRecord::Base
belongs_to :user
belongs_to :category
end
class User < ActiveRecord::Base
has_many :posts
end
class Category < ActiveRecord::Base
has_many :posts
end
I want to get all the posts that have a relation to user AND category. Is any similar possible:
user.category.posts
Or do I need to do:
user.posts.where(category_id: category.id)
You have 1-M relationship between User and Post.
In User model association should be has_many :posts (note plural)and not has_many :post(singular).
Update your model User as below:
class User < ActiveRecord::Base
has_many :posts ## Plural posts
end
To answer below question:
get all the posts that have a relation to user AND category
Assuming that you have local variables user and category as an instance of User model and Category model respectively.
For example:
user = User.find(1); ## Get user with id 1
category = Category.find(1); ## Get category with id 1
user.posts.where(category_id: category.id) ## would get you what you need.
Also, user.category.posts will not work as User and Category models are not associated.
Try:-
user.posts.where(category_id: category.id)
Change your association like
class Post < ActiveRecord::Base
belongs_to :user
belongs_to :category
end
class User < ActiveRecord::Base
has_many :post
belongs_to :category or has_one :category
end
class Category < ActiveRecord::Base
has_one :user or belongs_to :user
has_many :posts
end
in users table add column category_id,or add column user_id in categories,because you don't have relation between those two tables.if you don't have relation you can't use association API's.then you have to use manual API to fetch the data.like how you have mentioned your question.