How to make a resource that belongs_to multiple users in Rails - ruby-on-rails

I'm setting up an app that has Users and Brands. Most users will not be associated with a brand, and will only be able to comment on Brand pages. Some users, however, will be associated with a single brand. I want these users to be the "admins" or owners of this brand. E.g. Users A and B are both "admins" of a brand, and so can create/edit/update the brand, etc. My question is, how should I set up the Brand resource such that it "belongs_to" multiple users? I understand that I could say brands have_many users, but is it weird to say that an object "has" a user? Is it more appropriate to "belong" to users? This description leads me to believe so: "For example, it makes more sense to say that a supplier owns an account than that an account owns a supplier."

It's definitely a has_many relationship.
But it may be clearer to refer to those special users as 'administrators' or 'admins'
class Brand
has_many :administrators, class_name: 'User'
end
If it turns out that a user can be administrator for several brands, then you'll need a join table, either HABTM or HMT. HMT is the better choice in case you want to store characteristics about the join (e.g. when he became administrator)
class BrandUser
belongs_to :user
belongs_to :brand
end
class Brand
has_many :brand_users
has_many :administrators, through: :brand_users, source: :user
end
class User
has_many :brand_users
has_many :brands, through: :brand_users
end

Related

Rails Complex Active Record Relationship

I have a complex active record relationship in mind, and was wondering how exactly I would accomplish it. In essence:
A User can create a Board. A user can then add other users to that board for collaborative editing. Added users form a Team. Each added User has a Role in each board, (Admin, Editor, Viewer).
I was thinking of setting it up this way:
A User has many Boards
A Board has many Users through Teams
A Team has many Users?
The role part has been confusing me. Do I have to set up a TeamUser model which has many Roles, or does each User have many Roles which belong to a Board? Does a Role even have to be it's own model?
What is the most effective way to accomplish my goal?
If a user could belong to many teams and could have many roles, logic could be something like:
You need a join table to supply the N-to-N relationship between User and Board model. But the thing is, when you add a user to a board, you give them a role in that participation. It's a good place to hold role info in that participation. So our UsersBoards join-table transform into the Participation model (Or whatever you like to call it). Our participation model now holds the user, board and role info (All of them is foreign-key).
I didn't exactly understand the purpose of the Team model but I think it's easy to add a user to a team when it's necessary. It will not hurt to our logic.
Also, if you don't plan to add more features in the future, role can be an enum too.
class User < ApplicationRecord
has_many :participations
has_many :boards, through: :participations
end
class Board < ApplicationRecord
has_many :participations
has_many :users, through: :participations
end
class Participation < ApplicationRecord
belongs_to :user
belongs_to :board
enum role: [ :admin, :editor, :viewer ]
end
user = User.first
user.participations.first.board #Board
user.participations.first.admin? #true
user.boards
And you can add helper methods or delegate to models for shortening the query.

Rails 5 - belongs_to but has_many association

I am currently trying to create a system which allows for specific users to create a Course record which can be enrolled in by many other users. I've tried a few association techniques such as has_and_belong_to_many, has_many :through and number of other setups but have been unable to get it right.
Basically all that I need is the following:
Course belongs to (is created by) a single User (foreign_id => admin_id)
Course has many enrolled Users (Join Table?)
User has many created Courses
User can belong to many Courses
If you have any idea how this would be accomplished I would greatly appreciate your input.
I would use a Course model to represent the course information, with a user_id attribute to associate with the user who created the course. I would also make an association table/model called Enrollment which is an association between a User and a Course. You can then do something like this:
#User.rb
has_many :courses
has_many :enrollments
has_many :enrolled_courses, through: :enrollments, source: :course
#Enrollment.rb
belongs_to :course
belongs_to :user
#Course.rb
belongs_to :user
has_many :enrollments
has_many :users, through: :enrollment
With this configuration you can call course.user to receive the user who created the course, but you could also call course.users to receive the users who are enrolled in the course. On the opposite side, you can call user.enrolled_courses to receive the list of courses a user is enrolled in, or user.courses to receive a list of courses a user has created.

ActiveRecord relationship model with Users and Organizations

I'm trying to find out what's the best logical way to model relationship between models.
I have 4 models:
User
Product
SlackTeam
Organization
Here User has many Products, SlackTeams and Organizations, and SlackTeam belongs to User and has one Organization. Organization should belong to User and SlackTeam. Am I logically correct here?
The workflow is following:
Users can log in with SlackTeam (which automatically creates Organization)
other Users from the same slack team will be added to same Organization once they link up their account with Slack
if Users are connected to many SlackTeams (and Organizations) they can filter to see Products from all Organizations they are part of or only from one
Am I missing something?
class User
has_many :users_ogranizations
has_many :organizations, through: :users_organizations
has_many :products, through: :organizations
end
class Product
belongs_to :organization
end
class Organization
has_many :users_ogranizations
has_many :users, through: :users_organizations
has_many :products
end
class UsersOrganization
belongs_to :user
belongs_to :organization
end
# i'd rather use slack profile than team, because Organization and Team
# already connotes the same thing.
class SlackProfile
end
You can handle your user's login however you like, I would prefer a kind of authentication service, though. All products that belongs to the organization is now accessible to the user, you can then filter the products with:
current_user.products.where(organization: Organization.last)

Rails "Sometimes Has One" Relationships

This is probably a newbie question, but I can't seem to think of a good solution. I have a company table that has_many users through groups that can also be administrators of the company (enabling them to edit the company but only one company per user).
What's the best way to set this up in Rails?
I can't add an admin field to the user table, because it wouldn't discriminate which company he/she is administrating. But if I do a company_id field, what would that relationship look like in Rails (since it's a sort of somtimes_has_one relationship!). I could leave it without a relationship, but that doesn't seem proper...
Thanks in advance for any help!
From what I understand, you have a user which might belong to a company, and if it does, it might actually administer it.
You could setup Group to have for example, company_id, user_id and an admin field (this way you get to know which users belong to which company, and if they also administrate that company)
For a user to belong to just one company you could add a validation for uniqueness per two columns (company_id and user_id)
You could get one company's administrators by doing
class Company < ActiveRecord::Base
has_many :groups
has_many :users, through: :groups
has_many :administrators, through: :groups, source: :user, conditions: ["groups.admin = ?", true]
end
and call company.administrators or company.users for all users
You could also do something like
class User < ActiveRecord::Base
has_one :group
has_one :company, through: :group
has_one :administered_company, through: :group, source: :company, conditions: ["groups.admin = ?", true]
end
so you can call user.company or user.administered_company
and so on...

Rails User Membership Groups

I'm trying to make a application where a user belongs to multiple courses and multiple assignments belong to a course. I'm using devise for the user model. I want to be able to find all the courses a user belongs to and all the assignments their courses have.
User model:
has_and_belongs_to_many :course
has_many :assignments, :through => :courses
Course model:
has_and_belongs_to :user
has_many :assignments
Assignment model:
belongs_to :course
this requires an intermediate table CoursesUsers with columns user_id and course_id
and column course_id in Assignment
with this give you can do things like
current_user.courses
current_user.assignments
some_course.assignments
some_course.users
(assuming there is a current_user or some_course)
Read about details here: Active Record Associations Especially how to setup the has_and_belongs_to_many association

Resources