I want to creat an application where a User can create a Room and is the only owner of it. Other users should be able to join a Room, just one at the time and only they should be able to see what is happening in this Room.
So i created a controller rooms_controller and the model Room.
Btw I'm using devise to handle all the Userstuff.
So what should i put into the user.rb file? has_one :room? belongs_to :rooms?
How can users join a model?
Does a User have an one.to-one relationship with Room? In that case User has_one Room. Or can a User create many Rooms? A User can join a Room, if, for example, there is a Rooms_Visitors table where the RoomId and the UserId identify a row.
Its hard to answer without knowing your broad use case.
I advice that you study a bit on SQL relations, then the answer for your use case will become clear to you.
You can design the models this way. You can actually have two types of users: Owner and User and they can inherit from the BaseUser where BaseUser being the class with all the common user attributes.
And, your model associations can look like this:
class BaseUser < ActiveRecord::Base
# all the common user attributes here
end
class Owner < User
has_one :room
end
class User < BaseUser
has_many :rooms
end
class Room < ActiveRecord::Base
belongs_to :owner
belongs_to :user
end
owner has one room and room belongs to owner.
user has many rooms and room belongs to user.
You have to add owner_id and user_id in your rooms table.
You can also have a user_type column in your base_users table to indicate what type of user is this (i.e. owner or user).
Also, take a look at the cancancan gem which is an authorization Gem for Ruby on Rails application. You will need to have different types of abilities for example: owner will be able to create the room but user can't create the room, they can only join. You need to handle these things using authorization.
Related
I have a single users table through Devise. Branching off this table are 3 other models (author.rb, seller.rb and buyer.rb) with each having a one to one relationship with the main Users table.
The reason for this is each have some unique attributes and I want to keep the main Users table tidy. I am using active admin and want to avoid redundant fields when registering a new user.
Currently I am using enums to assign user roles:
enum role: [:author, :sellers, :buyers]
The problem is when I set a role it works in the sense that I can restrict what a user sees based on that role however there is a big issue I have below.
The problem:
I want to be able to register an Author. Everything good so far. But I also want to be able to register a Buyer and then associate that buyer with the author as two different users. At the moment a user is becoming both at the same time through nested forms in active admin I used which is not what I want. I want a user to be a buyer and the other user to be an author.
Maybe I don't have my relationships set up correctly for this? Or it could be a problem in active admin?
class Author < ActiveRecord::Base
belongs_to :user
end
class Buyer < ActiveRecord::Base
belongs_to :user
end
class User < ActiveRecord::Base
has_one :author
has_one :buyer
end
Basically I want to be able to register two different users and after that associate them and I don't know how to do this. Any advice much appreciated.
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
I have a Users class in my rails app. I need two types of users, 1) Players, 2) Managers. Users will all log in using Devise and have same basic user fields. I will have a League model. What is the best way to model this? STI doesn't seem quite right but not sure if Polymorphic works either since if both Manager < User && Player < User. The only real role a manager will have will be admin roles such as adding/removing players from leagues, setting up schedules etc.
class League < ActiveRecord::Base
has_one :manager
has_many :players
end
class Match < ActiveRecord::Base
has_and_belongs_to_many :players
belongs_to :league
end
class User < ActiveRecord::Base
has_and_belongs_to_many :matches
has_and_belongs_to_many :leagues
end
class Player < User
has_and_belongs_to_many :leagues
has_and_belongs_to_many :matches
end
class Manager < User
has_many :leagues
end
Any suggestions for the best way to set this up are greatly appreciated!
Using STI for players ActiveRecord is looking for Player table for the join but it doesn't exist.
STI can work for this, but since the difference between the types of users is basically a flag that says a user is an admin, you just need something on a user to check whether they are allowed certain actions. Roles can be either exclusive or inclusive (so that a user can be both a Player and a Manager), but once set up you can shape the interface around the capabilities a user has:
<% if #user.has_role?('manager') %>
<%= render 'manager_fields' # or manager_page, etc. %>
<% end %>
How you handle this in the controller depends on how you implement the roles, either via gems like Pundit, CanCanCan, etc. or through explicit checks in something you write yourself. The gems will give you helper methods to reduce the amount of typing involved in views and a more declarative syntax on the back end.
STI eliminates the need of separate tables for each class, given that most (or ideally all) attributes are shared between the two models.
In this case we'd add a new column in the users table called type which will indicate the class that this record will be parsed to, so either Player or Manager
As for the models
class Player < User
and
class Manager < User
As for the permission you could check if the user instance is of type Player or Manager
Of course you don't need to do STI if you don't want to, instead you'll create two tables players and managers and you'll need to join them with the User model, which would be tricky, since not all users have managers and not all users have players, so one or the other will always return nil, .. unless you create a polymorphic relation, but then you'll need to check the type of the object, .. idk
I think STI is your best solution, for the time being
I am creating an app where I have 3 different types of users. Each user type will have only 2-3 same columns and 4-5 columns which will be unique to that user type.
Example of user types:
Admin
Coach
Player
My initial approach was to create User table with columns admin, coach, player. These columns are booleans which define does user have certain role. Admin would have admin to true and all other columns to false.
This works fine if we all users have same columns like username, password etc. The problem is appearing when we introduce other columns which are unique to some user type. Let's say all Players need to have address. The we have these columns for user table:
id
username
password
admin
coach
player
city
address
apartment
zip
etc...
For player these columns would be populated, but for Admin and Coach these values would be null.
My second idea was to leave User table with values which are common to all user types:
id
username
password
admin
coach
player
And then create new tables which would be populated only for specific user type:
class AdminProperties < ActiveRecord::Base
belongs_to :users
end
class CoachProperties < ActiveRecord::Base
belongs_to :users
end
class PlayerProperties < ActiveRecord::Base
belongs_to :users
end
What would be the best practice to model this type of app with multiple user roles and columns which are unique to specific User? Thank you.
I would recommend to go with second approach of extracting user into different table, and then associating each admin, coach and player with them.
class User < ActiveRecord::Base
...
end
class Coach < ActiveRecord::Base
belongs_to :user
...
end
It not only help to keep your code DRY, but also keeps you flexible for modifications in child tables.
I have a base table called users which holds all common information about a user such as name, address, phone number...etc
I have another table called clients which holds specific information about a client (such as the client's company name and their url) and inherits user information from the users table. A client has a foreign key user_id which maps back to the information about a user.
I have another table called client_admins which hold specific information about client_admins and also has a user_id field AND a client_id field (which links to the clients table).
I have another table called super_admins which links to the users table and has specific information about a Super admin.
I know I could probably get away with Single Table Inheritance as there is not a lot of different data between each of the types, just different functionality and privileges.
What is the best way to model this in Rails 3?
Inside your user model:
has_one :client
has_one :client_admin
has_one :super_admin
Inside your client model:
belongs_to :user
has_one :client_admin
Inside your client_admin model:
belongs_to :user
belongs_to :client
Inside your super_admin model:
belongs_to :user
I am unsure of whether this is exactly what you were aiming for, but with my citier gem you could do this:
class User < ActiveRecord::Base
acts_as_citier
# User methods and validation, inherited by all children (so client & super admins)
# Useful for things like validating user permissions etc
end
class Admin < User
acts_as_citier
# Admin specific methods and validation, inherited by all children
end
class Client < ActiveRecord::Base
end
class ClientAdmin < Admin
acts_as_citier
belongs_to :client
# Client admin specific methods and validation
end
class SuperAdmin < Admin
acts_as_citier
# Super admin specific methods and validation
end
Allows each model to have unique fields so better than STI, but also shares methods and properties like normal inheritance.
Check it out - http://peterhamilton.github.com/citier/