I'm using Ruby on Rails 3.2.8 with Sorcery authentication.
What is the best way to create sub-users accounts?
Ideally, I would like to invite members by email and have them click on a link and they choose their username/password. Is it possible to do this within the same user table so they all can login from the same login page?
To wrap your head around what I'm trying to do is... Employer can add/invite employees to join the system and any data input to the system will belong to the employer.
Personally I would handle this as a single table inheritance model with a same-table association column.
Put a field called boss_id on your users table. You'll have the main User model, that has the Sorcery authentication stuff and any common logic. Underneath it you have Employer and Employee. They have a method called boss: for the employer, this returns self or nil (whichever you find makes most sense), whereas for employees, this is an actual association method, something like this:
class Employee < User
belongs_to :boss, class_name: 'User'
end
When an employer sends out an invitation, direct the invitees to a URL for invitations specific to the employer, like:
http://yoursite.com/employer/3/invitation
When the user creates their account you associate them to their owning employer.
When an employer views their data, ensure that you pull their child employees' data as well, using the users table as a join table:
class Employer < User
has_many :employees, class_name: 'User', foreign_key: 'boss_id'
has_many :contacts # Or whatever your application-specific stuff is
# that you want employers to see through their employees
has_many :employee_contacts, through: :employees, source: :contacts
end
If you need to assign ownership to employers in the database, I'd use an observer to watch for saves on the owned models, and if they are saved by someone with a boss, set an additional column to that boss' ID.
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 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.
I'm having trouble coming up with a way to structure my models to the the following:
I have Users through Devise - Users can have a role of (amongst others) Sales, Admin and Client. This is set through a HABTM with the Role model. I've set up a method so I can do the following
user.is? :Client
What I need is the following:
Users that have the Role of Sales can have any amount of clients.
So when a SalesPerson logs on, I can do User.clients to fetch all clients related to them.
Users that have the Role of Client can only have one client.
When a new Client signs up online, I want to create their user trough devise, and then also create a client through nested values, linked to the user they created.
Clients should have one SalesAgent, using the User model
When viewing the client, one should be able to have a dropdown to select the SalesAgent from. This should, as above, use the User model.
Clients should have only one Devise User with the role of Client, using the User class
Clients should be able to log on through devise to access their details, track orders, etc.
As you can see, this is incredibly confusing, and I'm not sure what the best way would be to pull this off. The only thing I can think of would be to use a HABTM between Users and Clients, and then Joins and hacks in the forms to make it work. Is there a better way to do this? I've looked at perhaps using
has_one :sales_agent, :class_name => "User"
But can't get it working. :/
Rather than overloading the User class with a roll-your-own single table inheritance scheme, it's often better to break out the roles in the db. It sure makes things clearer at this stage, and it's a better way to store data specific to clients or sales agents that don't belong to any user. E.g.:
class User < ActiveRecord::Base
has_many :clients
has_many :sales_agents
end
class Client < ActiveRecord::Base
belongs_to :user
belongs_to :sales_agent
end
class SalesAgent < ActiveRecord::Base
belongs_to :user
has_many :clients
end
I've been watching Ryan's screencast:
http://railscasts.com/episodes/196-nested-model-form-part-1
I have a similar but different problem, and am hoping someone can help.
I have the following four models that are required (at minimum) to register:
Account
Company
Address
User
At registration, I'd like for Company, Address, and User to individually be associated with Account directly.
Also, I would like te User to be associate with the Company, and the Address to be associated with the Company.
Note: Each has a foreign key: account_id -- This is essentially a multi-tenant system with a single database.
My associates are currently setup as follows:
Account
has_many :companies
has_many :users
has_many :addresses
(In the future, other models will use the Company and the Address model, that is why Account has many of those)
User
belongs_to :account
belongs_to :company
Company
belongs_to :account
has_many :users
has_many :addresses
Address
belongs_to :account
belongs_to :company
I've been using accepts_nested_attributes_for method in the models, and the fields_for method in the views, but have only been able to get things associated in a purely nested way.
In other words, a User gets associate to a Company, but is not associated to an Account.
I need for each of the models to be associated with the Account. (Except for Account itself of course)
Is there a way to do this?
Thank you.
I think you confuse some where.
Account Has Many Companies
Company Has Many Users
Company belongs to account
account User belongs_to company
user belongs_to account either through company or create account_id in user
In views you can create form company and then create fields_for for account and inside account create fields_for user.
I think this will solve your purpose.
don't forget to add accept_nesetd_attributes inside company and account
Let's say I have a User model and I want to have different user roles. In a single application, you can simple store the role a string, or as another model and that's fine.
But what if you want to store more associations for the individual models? For example, let's say Admins contain links to collections and belongs to many collections that regular users should not be associated to? In fact, other users will be linked to a whole other set of models that Admins do not have.
Do we put all of the associations in the User object and just ignore them based on the type of the user? Or do we start subclassing User (like in Hibernate) to only contain the associations and model logic for that user type?
What is the way to do this in rails? Thanks!
I would suggest using Rails Single Table Inheritance. Essentially, you'll have a users table in your database, and a root User model. Multiple models (one for each "role") can inherit from User, and have their own associations:
# Regular users have no associations
class User < ActiveRecord::Base
end
# Admins have collections and notes
class Admin < User
has_many :collections
has_many :notes
end
# Editors only have notes
class Editor < User
has_many :notes
end