How to set up a typical users HABTM roles relationship - ruby-on-rails

I'm quite new to this and I'm using cancan + devise for my user auth. However I'm not really sure what it means to set up a typical users HABTM roles relationship nor do I really understand what a HABTM relationship is.
Can anyone explain it really well or point me to a good tutorial or example?

HABTM means has and belongs to many. You basically need a table as a middle man to track multiple id's (called a through table). When referenced as a typical users HABTM roles relationship, they really mean there would be a User model, Role model, users table, roles table, and a roles_users table. Don't forget to add the the HABTM -- roles_users -- table. A typical setup follows:
class User < ActiveRecord::Base
has_and_belongs_to_many :roles
end
class Role < ActiveRecord::Base
has_and_belongs_to_many :users
end
You can then use the associations like normal saying User.first.roles and Role.first.users.
There are also a couple Railscasts on your issues.

The Ruby on Rails Guides are a good starting point here also this tutorial is exactly what you want

Related

Devise and multiple users models

I'm fairly new to Rails and trying to setup an app that uses several types of users: Teacher, Student, Admin (and likely more to come).
The reason I want different models is because the attributes for the various users differ. For example, Teacher have topics taught, a profession, and a diploma. Whereas Student and Admin do not. Students can leave reviews of teachers, etc.
I thought of having a general User model for the general information such as name, email, and other contact information and each type of user would inherit of it:
class Admin < User
end
class Teacher < User
end
class Student < User
end
And so on.
I'm using Devise for authentication and used STI for differentiating between user roles through a role field in the table.
The thing is, where and how can I tell my app to generate a current_user of the right class when the user logs in? And where should I store the additional info on each model (ex the profession of a teacher). In the users table?
About the relationship with their objects, for example, a teacher has many topics he teaches. How can I make sure only teachers have topics and not students?
I've looked into CanCan but was utterly confused.
My advice is : DONT DO THAT ! You are mixing very different concerns and will end up with the infamous God Object.
User is here only for authentication, you should not mix it with your domain models. Teacher / Student / Admin etc should be separate models from User. You can eventually create a People table and have Teacher Student and Admin inherit from it.
class Student < Person
Or have a different table for each of them so there's no possible confusion (also someone might be both a Teacher and an Admin for example, separating stuff keeps your options open)
But whatever you choose keep User out of it !
If you want to tie a User to Teacher / Student / Admin use associations and give each of them a user_id.
class Student < ActiveRecord::Base
belongs_to :user
end
Please have a look into this link. Hope this may helpful to you:-
http://funonrails.com/2011/12/multiple-resources-registrations-with/
Also, you can manage relationship with their objects by making model(table) as polymorphic like:-
# Topic Model:
belongs_to :readable, :polymorphic => true
Also in topic model there are two more fields:-
readable_id and readable_type.
# Teacher Model:
has_many :topics, as: :readable
# Sturdent Model:
has_many :topics, as: :readable

Rails - both model are has_many

Sorry, I am not very advanced in mapping out databases
I have a model similar to this: A teacher can have many students, and a student can have many teachers. So How would I make this? If a student could have only one teacher I know I would set an attribute like: teacher_id: integer, then when I want to create a student it would be similar to this
Student.create(:teacher_id => id)
or query similar to this:
Student.where(teacher_id: id)
Teacher.find(student.teacher_id)
But I am unsure of how to accomplish this if both are has_many relationships
You can use rails has_and_belongs_to_many relationship for your requirement. check this link for reference: http://guides.rubyonrails.org/association_basics.html#has-and-belongs-to-many-association-reference
you need to use this relationship like this:
teacher.rb
has_and_belongs_to_many :students
student.rb
has_and_belongs_to_many :teachers
then you need to add a migration to create a join table containing teacher_id and student_id
you should create name of your migration in alphabetical order like this:
rails g migration create_join_table_for_students_teachers student_id:integer teacher_id:integer
and then rake db:migrate
then you can access students of a single teacher like teacher.students etc.,
Hope this might help you in some way please go through the reference link once
You're describing a has-and-belongs-to-many (HABTM) relation, which Rails supports in two ways: has_and_belongs_to_many or has_many :through. You can read about them in the Active Record Associations Rails Guide, which also gives you tips and how to choose which one is appropriate for your application.
Better use has_many:through relation.

How do I define many to many associations and the related properties in Rails (Active record)?

I am wondering how do I add additional properties to a many to many relationship.
I have two models that share a many to many relationship, Company and Profession.
Many professionals could belong to a Company
So my Company model looks like below
class Company < ActiveRecord::Base
has_and_belongs_to_many :professions
end
The same people in the same profession could belong to multiple companies as well
so
class Profession < ActiveRecord::Base
has_and_belongs_to_many :companies
end
Now I need to associate an hourly rate which could be different for each of the companies for the same profession. I am not very sure where to introduce the hourly rate property? Even if I were to add that to the joining table, how do I access that rate using active record?
This is a typical scenario where you select has_many through over habtm. As a rule, if you only need to associate two models, no other info needed to be stored in the association, use habtm. For most cases, you have to use has_many through. You case falls under this scenario.
You want to save the hourly rate in the table that associates a Profession and a Company. If you have existing data that you want to migrate, you may want to look at this post How to migrate has_and_belongs_to_many to has_many through?. If you can drop the joins table you use for the habtm association, just drop it and create a new table.

2 Way Friendship between different models

Ruby on Rails App.
I have two kinds of users,
Company
has_many :employees #sample
Employee
has_one :company
I want to create friendships between these two models, keeping track of the requester of the relationship (.requested_relationships) and the receiver (.pending-relationships) as well as the status (accepted, pending, etc). I can easily create the relationship with a third model and has_many :through ... BUT that wouldn't allow me to track who initiated the relationship and thus distinguish between pending and requested relationships. What is the correct way to model this?
I've been playing around with a polymorphic attribute on the relationship model, but without concrete success.
you can try to use amistad gem
very good for friendship relationship and has a very good documentation that can help you out alot. just check it out

rails attaching database entry to logged in user

I'm new to rails and am done setting up my login system. However, I want someone to be able to make a new blog post and attach it to their account when logged in. How can I attach a post to their user_id as well as list all their previous posts?
Define a model posts ( should have column name user_id )
model Post < ActiveRecord::Base
belongs_to :user
end
In user Model
model User < ActiveRecord::Base
has_many :posts
end
With the above defined associations user_id will be a foriegn key to User model so you can
get all posts by user something like below
User.find(id).posts
There are quite a few different approaches, but John Nunemaker's user_stamp gem is pretty straightforward and simple to get running.
https://github.com/jnunemaker/user_stamp
Just add a creator_id and updater_id to your table, a single line in your ApplicationController, and it'll do the rest!
You can associate models with each other by following this guide on rails associations. One solution for you might be:
class Post < ActiveRecord::Base
end
class User < ActiveRecord::Base
has_many :posts
end
You just have to make sure that your posts table has a column called user_id. Assuming your user table is called users. this will set up a one to many association between users and posts. From a User instance you will be able to do user.posts and get a list of the associated posts for that user.
The guide is much better at explaining this stuff and it's worth your while to read the whole thing--even the parts you don't need right now.

Resources