In my rails app, I have a user model with other fields and associations in it. Now I want, my users can make many projects and a project can have many users as members in it. And, the owner of the project is the one who created it. So, the whole scenario is Users can be owner or member and can be part of many projects. I have made my user using devise and I am using mongodb as my database. My user model has already many fields and associations in it, now I am struck at defining associations and relations for the above mentioned problem.
I have found one similar article with Active record: https://coderwall.com/p/rqjjca/creating-a-scoped-invitation-system-for-rails
But I want to execute all using mongoid and rails 4.
The solution for above problem is not so hard, as mongoid allows has_and_belongs_to_many association in rails, we can associate as:
In my users.rb:
has_and_belongs_to_many: projects
In my projects.rb:
has_and_belongs_to_many: users
Later we can also define roles of users as admin and member according to our requirement.
Related
I am trying to have Devise create a single User model and have different roles be a separate model. My User model (from rails g devise User) has a email, first name, last name, and role field.
The roles are admin, spectator, competitor. So, I created admin, spectator, and competitor models who all inherit from the User model.
I followed the top answer from devise and multiple "user" models and I can create a user. However, my competitor model migration also has other information such as contest name and location that are not required for the other models. When I do Competitor.create() and put in the necessary information for creating a devise User, the User gets stored in the database even though I have null constraints on the competitor model for contest name and location.
When I do Spectator.all, the recently created competitor data shows up which I thought it shouldn't....
My question is how should I be setting this up so that a competitor user doesn't get created unless his contest name and location is provided.
Another question is why when I do Spectator.all is the competitor's information displaying?
There is a much better way to use devise for multiple users.
Use Rolify Gem
It makes development much easier faster and more secure. You can have the configuration as per your requirement in the question "Single User model and each roles have a separate model"
Tutorial for using Rolify gem + Devise by Rolify Gem developers
If you want an authorization system, so go for CanCan created by Ryan Bates. With CanCan you can have many Roles. I am using it with devise with no problems. See Role Based Authorization and Separate Role Model. And check this ScreenCast about CanCan
The application I'm building is to allow users to download vouchers. Employers sign up for an account, add employees (who get a login), select which vouchers to enable, and then employees can see the enabled vouchers and download.
I initially created two devise models: employee and employer. This was so active record associations would be simple (employer has_many employees, employee has_many vouchers). But this would also mean separate database tables and therefore separate sign in forms.
I looked into single sign in forms for multiple users and this seemed to have the consensus that you should instead have a single User model and use CanCan and Rolify for permissions. But the problem with that is you cannot (I believe?) do active record associations between these two roles (not separate models).
I next looked at subclassing so I could do associations, but it has issues as people say Rails isn't really meant to subclass, and it seems a bit hacky.
So I'm left feeling like I have to choose the lesser of evils, whereas I really just want to find the right way.. Thanks in advance for any help.
So a friend of mine solved this very elegantly for me, for everyones reference:
Good question. It’s a great problem that deals with the intersection between good engineering (model implementation, database design) and user experience (single sign in form).
Assuming that Employees and Employers differ enough, it makes sense to implement them as separate models. But it also makes sense to have a single sign in form—employees and employers shouldn’t have to care that they’re signing into the right form.
Single table inheritence usually appears to be the ideal solution, but tends to best be avoided in Ruby on Rails applications unless absolutely necessary.
I’ve actually thought about this problem before, so I would suggest an implementation along these lines:
An Employer model.
An Employee model.
A SignIn/Login/Credentials/WhateverYouWantToCallIt model.
In terms of employer/employee associations, as before:
Employee belongs_to :employer
Employer has_many :employees
Now, considering that both models are able to sign in, it makes sense to separate these credentials into their own SignIn model. If you do some reading up on polymorphic associations (http://guides.rubyonrails.org/association_basics.html#polymorphic-associations), you’ll find that they are awesome for creating relationships where the association can be with different models.
So now you need to create associations between sign in credentials and employers and employees:
SignIn :belongs_to :signinable, polymorphic: true
Employer has_one :sign_in, as: :signinable
Employee has_one :sign_in, as: :signinable
The elegance of this solution (in my opinion), is that you’re able to separate your SignIn, Employer and Employee models, which not only conforms to good Ruby on Rails conventions, but is good database normalisation practice. At the same time, you have a SignIn model that makes it trivial to implement a better sign in form experience that allows both employers and employees to sign in.
I've been working my way through Rails 3 In Action and one element is confusing me.
Why doesn't User have a has_many association declared with Projects? Project has_many Tickets. What is it about the relationship between User and Project that differs from the relationship between Project and Ticket?
I would post code, but I think this question will only make sense to someone who has worked through the book (and therefore has the code to refer to).
A user never needs to have many projects, because the way that projects are shown to a user is through a scope on the Project model. If you wanted to have this association, then you will need to have a user_id attribute on the Project instances.
Currently I'm using Devise & CanCan which allows me to create
Users with Roles using a (Roles_Users) table.
That's nice, but what I want is to Have Projects in my app and for
each project for a user to possibly have a role like (Admin, Viewer,
etc) IE, roles are not assigned to users but to users based on what projects they are a member of.
Examples:
User X belong to Project A with an Admin Role
User X belong to Project B with an Guest Role
User Y belong to Project B with an Observer Role
What kind of Model would work for this?
Models
Users
has_many: projects
Projects
?
Roles
?
Users_Roles_Projects (user_id, project_id, role_id)
What do you think? I'm a newbie and could use the understanding and
thinking from you fine experienced folks. Thanks!
You should have a look in to has_many :through. This Railscast should get you up and running: http://railscasts.com/episodes/47-two-many-to-many
For example, you could have User has_many Projects through Memberships (I'm sure you can come up with a better name!)
Your Users model would contain the standard user details, the Projects model would contain the project details and presumably you have some Roles model somewhere (I've not used either of the libraries you mentioned so I can't comment in terms of how they work). The key is the Memberships model.
The membership model would contain the userID, projectID and a roleID. In the database there should only be one instance of any given userID and projectID pairing so by storing the roleID along side this pairing you can assign the role to that user on the specified project.
While playing around with Rails (since I am a newbie) while reading Agile Rails book I came across an issue using the Gem Authlogic that I don't know how to address.
I have a simple business Model. The tables store the following information: Name, Address, Latitude, and Longitude.
The above approach has been working fine, because using the console I can enter the information and it shows up, where I need it to.
My issue now is that I want to add authentication to it. As in assign those records in the table, to individual accounts. Since Authlogic is an authentication gem, can this be done?
What I am trying to get to here is that, I enter a few records and leave it at that. Few days later, I want to assign those individual rows in the table to an authlogic model so the person to whom the record should belong can authenticate to it and make changes.
Any code samples, blog posts to better help me understand would be great!
Thank You.
Authlogic will create a model called users. Let's say your model is called persons. You add a user_id field to your persons model and link them by association:
class Person
belongs_to :user
end
class User
has_one :person
end