Multi - User Multi Environment - ruby-on-rails

I'm looking to create an app, where each user can create their own... "Universe" in a way, with the amount of items and names that makes sense to them, etc.
I've never done this before, so far I've had the typical cases where you have users and admins, but they're both looking essentially at the same thing. Here each user will have a separate environment.
Obviously a user should not be able to see someone else's environment.
Can someone please point me to the right direction on this subject? Maybe some useful gems or resources I could use to get started?
Any advice is welcome!

I'd start with using a plugin for authentication, e.g. AuthLogic or Devise are two popular examples.
Both of these let you define a User class.
Then, when you are showing the user their stuff in their environment, you can make sure you only show them their own stuff by using has_many, and has_one, and has_and_belongs_to_many relationships in rails.
e.g. if it was facebook, you might have something like this
Class User < ActiveRecord::Base
has_many :news_items
has_many :friends
has_many :messages
end
In your code you could then refer to
#user.news_items
#user.friends
#user.messages
And the relationships would ensure you were only showing information belonging to that user.
(Caveat: in reality the relationships will be more complicated, and you will probably need more complicated logic, but this should get you started)

Related

Parent/Child classes in Devise

I'm newish to Rails and working on a project that I would like to create a parent/child relationship using devise. I've looked through a good bit of the literature on Devise, but didn't see any clear cut way to do what I'm trying to accomplish (though it's certainly possible I overlooked the answer because I was using different terminology).
Here's what I'd like to do:
Companies sign up using the normal devise registration flow with a little extra information - i.e. Company name, address, etc. They then add 'users' once inside the application. Users shouldn't have an external sign-up flow. I would like to each user to inherit the company information from Company.
Here is what I thought I'd try:
Generate both the Company and the User devise models.
Generate the User controller, modify the new action to #current_company.user.build
Would this accomplish what I'm trying to do?
Any further reading that you might be able to pass along would be appreciated!
Do this....
#app/models/company.rb
class Company < ActiveRecord::Base
has_many :users
end
#app/models/user.rb
class User < ActiveRecord::Base
devise ....
belongs_to :company
end
This is a has_and_belongs_to_many association.
What you should be doing is leaving companies to be its own model; don't include Devise on it at all.
Instead, you should make your User model the only one with the authentication. After that, each user will have to be related to a particular company (or if you wanted to use has_many :through, you could have a user a member of many companies).
You'd have to scope the Devise authentication around a company (IE company.users.exists? user); I've been working on that but don't have a thorough implementation yet.
There's a good ref here: Scope login to subdomain
This will allow you to have users for a particular company; which you'll be either be able to scope using subdomains (to make a crude "multi tenant" app), or to have a select box at sign-in or something.
Obviously, your lack of input means I've got to write a broad answer.
If I were you, I'd think about your desired flow.
Research multi tenancy with Rails (the apartment gem is good if you're using PGSQL) - this should give you a better idea on the way the application should work (IE how does a company need to support users).

want to give access for many organsation

We are developing a online rails application for schools, but we want to separate that all schools to each other.
Like slack website that manage many organisation from one application and organisation only access that data.
Also like trello, they also separate organisations in one application.
So what is the best approach is use for such type of application?
How we implement this in our ruby on rails application,that we separate all schools in our Database?
Okay.
Multi Tenancy
If you're coming from the world of "native" software, you'll be best reading up on multi tenancy:
(source: theenterprisearchitect.eu)
Rails apps are multi tenant by virtue of them running through a network; they run a single instance of an app, which is then accessible to anyone on that network (remember, the Internet is a huge network).
Rails provides all the functionality you mentioned above, with the added benefit of having a lot of world-leading companies using it to run (Twitter, AirBnb, Groupon etc have all famously used Rails).
You need to read up on database system design for your application, specifically...
MVC
To better understand how you'd make an application like you referenced, you need to understand the MVC (Model View Controller) programming pattern, and it's value within the world of object-orientated system design, especially pertaining to Rails:
Rails, like many other frameworks, uses MVC to build objects. These objects are defined by the programmer, but basically allow you to create the relevant data required to provide functionality to an application like you mentioned.
Specifically, each time you access a Rails app - you'll be essentially manipulating objects filled with data from the db. I'll explain any specifics in an update if you need it.
In regards your question, the way to integrate multiple organizations/entities into a single application is to set up the database schema to manage the organization as the "parent", with users and data as extra elements:
#app/models/company.rb
class Company < ActiveRecord::Base
has_many :users
has_many :invoices
has_many :clients, through: :invoices
end
#app/models/user.rb
class User < ActiveRecord::Base
belongs_to :company
has_many :invoices
end
#app/models/invoice.rb
class Invoice < ActiveRecord::Base
belongs_to :company
belongs_to :user
has_many :clients
end
This will give you the ability to use something like the following:
#config/routes.rb
constraints Account do
root "invoices#index" #-> http://company.url.com
resources :invoices #-> http://company.url.com/invoices/3
end
#lib/account.rb
class Account
def matches?(request)
Company.exists?(request.subdomain)
end
end
You'd then be able to use Devise to sign the user into the organization, allowing them to add / edit invoices as they need.
Each time you edit or update an invoice, a user will be assigned to it, allowing you to determine who created it etc.
Without going deeper into the code, that's what I think you need to know.
As concern of database design, you can design something like:
You should manage a organization model where each organization must be a sub-domain and your other model like User etc.. should be associate with organization model.You can extract the subdomain name from request url (like request.host, request.subdomain etc..) and find the records as per this subdomain request.
As concern of resource permission you can use cancan gem where you can manage resource accessibility through a single file.
https://github.com/CanCanCommunity/cancancan
Hope it is helpful for your initial design.

Multiple devise models vs permission based

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.

bottom up rails app associations

I'm building a rails app from the bottom up and need a little guidance on the model associations.
We have clients and engage them on multiple projects.
The client has users (their employees) who work on projects and make contributions to the project with files and notes.
We also collaborate with our clients on projects (add files, notes).
Projects have contributors (users or sub contractors that may be part of another client) who make contributions (files, notes).
So model wise I want to ensure I'm capturing everything properly.  Here's what I have, but I'm not confident its all right and am open to other associations.
Client
 has_many :projects
 has_many :users
Project
 belongs_to :client
 has_and_belongs_to_many :contributors
 has_and_belongs_to_many :contributions
User
 belongs_to :client
 belongs_to :contributor
 has_many :contributions
Contributor
 has_and_belongs_to_many :projects
 has_one :user
 has_many :contributions
Contribution
 has_and_belongs_to_many :projects
 belongs_to :contributor
I think contributions will be associated with models for files and notes; projects may be associated with a "next steps" model... All as nested resources I think.
Thanks
Have you reviewed the guide on associations? Did you do any sort of paper prototype of the model domain to clarify all these associations? Those are important parts of the process that for any moderately complex problem domain will be important for getting things off on the right foot.
I would probably make the :contributor association on Contribution a has_one association rather than belongs_to but that's probably just preference. I also agree with Phobos98 that Contributor is an unnecessary distinction from User. I think Contribution is a very nicely conceived model for relating user actions to projects. Most authentication frameworks like Devise allow you to specify roles and something like cancan would allow you fine-grained control over the permissions.
As far as nested resources go, that's really something different that just relates to how your app makes its data available. It's like building a house. You put up the walls and there's people and belongings inside, but the number of windows (routes) controls who can see what. Yes, it's helpful to have these routes available but they're not required at the beginning in order to make sure the data model is in place.
Did you actually try the model you have here and see if it worked? With scaffolding, you can try things quickly, and Rails makes changing the data model trivial, so there's no reason you can't be a little more agile with this. Just try it out and figure out what works and what doesn't. Then, you'll know what needs to change.

Is has and belongs to many suitable

Am new to this site, looking forward to getting more involved :)
I'm creating a customer ordering system using rails3, devise, cancan etc.
In brief, we three models:
Users
Companies
Orders
I'm struggling to understand the relationships though. Initially the users had many companies and the companies belonged to a user.
However, we actually have two sorts of user:
The admin staff here who can create companies, update details etc.
Our customers who can login and see only their companies and related orders.
I thought about creating two controllers - admin and users but it seems unnecessary and not very rails. Plus cancan can do all that I think.
What do you think we should do here? We were thinking about using the has_and_belongs_to_many relationship but most people online seem to say avoid it.
Thanks,
Jenny
--- edit ---
Thanks to all of you who've helped!
After some reading, I decided to use the has many through association.
I created a new model called agreement and set my models up as follows:
class User < ActiveRecord::Base
has_many :agreements
has_many :companies, :through => :agreements
end
class Company < ActiveRecord::Base
has_many :agreements
has_many :users, :through => :agreements
end
I'm a little stuck though and can't find a good example online.
Should I be creating a user and company separately and then create an agreement to match the two up?
Again, thanks for the help All.
Given the description it sounds like you have:
Users
Customers
Companies
Orders
The Admins are Users who have the role allowing them access to the create,update on the companies. A customer belongs to a company and may also be a 'user' depending on the information you store in the User model.
As for the HABTM it's still ok to use if you aren't putting additional data within the join table. Typically though you'll have some information in the join table since it provides additional context to the join.
A nice resource for sample data models, and to give some ideas around the Entities and relationships is Library of Free Data Models
You can go with has_many :through .As it seems application will surely need some continuous changes in the coming future.So in this case it will be helpful
Reply if any queries
Thanx
First, you need to know what you really want to achieve, understand the relationships and how the relationship needs to look like. Draw some entity relationship model on paper, that helps.
Personally, I prefer to user has_many :through because if you need to store additional data for that relation (which may be the case when extening your app) you're already set and don't need to migrate your tables and models from habtm to has_many :through.
For the user permissions, stick to cancan.

Resources