create relationships for STI child - ruby-on-rails

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

Related

Rails: How to setup multiple relation types to same models

I have a Product and Category model which have a has_and_belongs_to_many relation.
So I can search for Product.categories or Category.products
class Product < ApplicationRecord
has_and_belongs_to_many :categories
end
class Category < ApplicationRecord
has_and_belongs_to_many :products
end
Now I wanna add a new relation to the Product:
It should called main_category which only should be a has_one relation from the Product to the Category. So a Product only can have one MainCategory. But the Category of course should return all MainCategory products.
Must I create a SubClass of Category? Normally I would like to not create an extra class
How can I solve that to simply call Product.main_category or Category.main_products?
How to place indexes properly?
How does the migration should look like?
You can simply do it like this i guess
class Product < ApplicationRecord
has_and_belongs_to_many :categories
belongs_to :main_category, class_name: 'Category', foreign_key: :main_category_id
end
class Category < ApplicationRecord
has_and_belongs_to_many :categories
has_many :main_products, class_name: 'Product', foreign_key: :main_category_id
end
You will have to add an column to products table called main_category_id
Source https://guides.rubyonrails.org/association_basics.html#bi-directional-associations

Rails possible problem with has_many polymorphic association

In my application, I have the following models:
User
Psychologist has_many classrooms
Teacher has_many classrooms
Parent has_many children
Director belongs_to school
Coordinator belongs_to school
My user model looks like the following:
class User < ActiveRecord
has_many :roles
def has_role? role_name
self.roles.where(role_type: role_name).any?
end
end
The Role model is polymorphic:
class Role < ApplicationRecord
belongs_to :user
belongs_to :roleable, polymorphic: true
end
And the other models are rollable.
My question is the following, it seems that this is not correct, because some models like: Director, Psychologists, Teachers, Coordinator and Parent. They only have relationships and their database tables do not have any other column except created_at, updated_at.
Is it okay to only create these models with relationships and have their tables without data?
Maybe you intend to use single table inheritance and not polymorphic relationships. If a Psychologist is a User, it should be the case.
Then you need to add a type column of type VARCHAR to the users table, and set up your models like:
class User < ApplicationRecord
has_many :roles
def has_role? role_name
self.roles.where(role_type: role_name).any?
end
end
class Psychologist < User
# no need to set up roles
end
class Teacher < User
# no need to set up roles
end
class Role < ApplicationRecord
belongs_to :user
# no polymorphic
end
The type column will be populated with the name of the actual class, like "Teacher" etc.
As an instance of Teacher is also an instance of User, it will have teacher.has_role?('foo') and teacher.roles, and you will be able to create a role like Role.create(user: teacher, name: 'bar').

Change many-to-many association to one-to-many

I have two models:
User
class User < ActiveRecord::Base
has_and_belongs_to_many :partners
end
and Partner
class Partner < ActiveRecord::Base
has_and_belongs_to_many :users
end
and now, i want change it to:
class User < ActiveRecord::Base
has_many :partners
end
class Partner < ActiveRecord::Base
belongs_to :user
end
but how can i do it by migration?
You can change the model's to:
class User < ActiveRecord::Base
has_many :partners
end
class Partner < ActiveRecord::Base
belongs_to :user
end
And Partner model should have a user_id column
If you don't have a user_id column in Partner model, you can add it by:
rails g migration add_user_id_to_partner user_id:integer
The intermediate table partners_users should be dropped since it is a has_many Association.
To drop the table create an empty migration and then add this to the migration file.
drop_table :partners_users
Then run the migration using rake db:migrate

Possible to filter an ActiveRecord query based on multiple "belongs_to" relations?

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.

composite key associations in rails 3

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

Resources