Ok use for Single Table Inheritence? - ruby-on-rails

I have the need for a user and a contacts model, both have common attributes like first name, last name, sex etc. It thus seemed reasonable to create a model individual and have user and contacts inherit from that model.
class Individual < ActiveRecord::Base
end
class User < Individual
end
class Contact < Individual
end
My question is, what type of security problems would I open up by having the above setup? I'm using authlogic and all of its required fields are within the individuals table. The above method seems easy, and yet I'm worried I may open myself up to unforeseen security issues, any thoughts? Just to be clear a user can login and a user will have many contacts.

Using STI doesn't open you up to any new security issues as they are orthogonal..
However, STI may upset your DBAs as you will have null fields within that table. (attributes that are present in one sub classed model and not the other)
As from the design stand point, what are you achieving by having such a model relationship. If the only distinction between a User and a Contact is that a User can log in and can have numerous contacts then you can simply have an individual that can have many contacts (which map to Individuals) AND can possibly have login credentials
Remember that a contact may be shared by numerous individuals which stipulates either a has_and_belongs_to_many or has_many :through
hth

Conceptually I wouldn't mix them. The underlying intent/function of each model is substantially different, so the fact that they look similar in shape is a red-herring.
Potentially you'd run into a problem where someone could figure out a way to authenticate with a Contact, although it doesn't seem very likely, given its unlikely that you assign a username to a contact, or the secret hash stuff. But it would be possible if there is a bug in AuthLogic, or if someone tried hard enough to hack your setup and you weren't anal about protecting against injection attacks.
Also, there are performance reasons to not do this if your app grows a lot. Basically, I think its a bad design to have these two models rely on the same table for fairly superficial reasons.

Related

What's the best approach of deleting users from database with many relations in peer-to-peer marketplace in Rails 4?

This is probably a complicated one, but I'll give it a try.
We have a Rails app - peer-to-peer marketplace with lots of registered users in beta testing. Users have many items for sale and swap. User will get offers from other users that want to buy or swap their items for user's items. Those items might also be wished by other users. Items have many likes and comments from other users and there are also notifications implemented for each action.
In short there's lots of one-to-many, many-to-many and polymorphic relations in Users and Items table.
Some sneak peak into model complexity:
class Item < ActiveRecord::Base
belongs_to :user
has_many :wishes, as: :wishable
has_many :listing_likes, foreign_key: 'listing_id', class_name: 'ListingLike'
The question is, what's the best way to approach user account deletion and keeping Data Integrity in this case. Hard deleting and dependent: destroy is not an option, because it will break the user experience to other registered users.
The only thing that comes to mind is to add deleted boolean field to users table and to create a check function if the user was deleted, including this function basically everywhere in the app just to make sure that this user wasn't soft deleted and to display a greyed out user name that is not clickable anymore. That approach will probably take too long to implement and will be pretty hard to maintain.
Any advice for better approach will be appreciated. Is there a common approach, best practice or just an advice for how to treat it the less painful way?
Thanks in advance
I think your initial thought of implementing some form of "soft delete" is the way to go. When you build a complex network-like data structure you can't (and often don't want) to remove a single piece.
You might be surprised at how easy this is to implement yourself, but you don't need to implement it yourself: check out Paranoia, which implements a fairly robust approach to soft deletion.

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.

not sure whether to create new models

I'm making an app with Rails that, among other things, allows certain types of professionals to create an online profile. So there is an 'association' between the User and Profile model. I created the Profile model so that I can basically restrict the User model to name and registration information, and keep profile information elsewhere (i.e. 'normalize' the db as I think it's called)
However, these profiles (as is often the case, on LinkedIn, for example) contain a lot of information. For example, there will be a section for Work Experience that sometimes looks like this, where a user can add many different work experiences.
and then something similar for education
And many other different types profile information. Note also, that the ability to add to and edit these discrete categories takes place in separate forms. I can add to my work experience without touching education.
My question is, should I try to store all of this information in my Profile model? Or, would you, for example, create a WorkExperience model and do something like Profile :has_many work_experiences? and something similar with EducationExperience, or is there even another way to do it?
One of my concerns is queries on the DB. For example, in terms of performance, is there going to be much of a difference if, in the show action of the Profile controller, I do queries for WorkExperience.all, Education.all rather than storing all the information in the Profile model?. Another concern is just general code organization for profiles that can become quite large.
You'll have the cleanest code (and decent performance) by splitting out something like Experience (which will belong_to Profile), along with a type column that determines whether it's "work" experience, "education" experience, etc. That's the approach I would take, unless the different types of experience have vastly different columns.

ActiveRecord relations between models on different engines

I'm building a Rails app that is probably going to have a large amount of models. For now let's say that i need to have Users, and each User will have a personal Blog
I've been developing the User-related part on a separate Engine (let's call it AuthEngine) that encapsulates the User model, authentication, etc. At the time this seemed like the best approach
In parallel, my colleague was developing another engine, to deal with the blog features (let's call it BlogEngine).
Now he needs to access user data which is stored in the other engine. He achieved this by defining:
BlogEngine.user_class = "AuthEngine::User"
This way, he can easily ask for user data, even though it isn't stored in the same engine. The problem comes when we want to define relashionships between models
He can easily say that each blog post belongs to a user
has_one :user, :class_name => BlogEngine.user_class
But as far as i know he can't specify that each User has multiple posts since the User model is within the other engine
The consequence of this is that he can't do things like #user.posts, but instead has to do Post.find_all_by_user(#user)
Is there a more elegant way to deal with this?
I also considered the possibility that each engine could simply generate the models inside the app, removing the encapsulation, but since the amount of models will grow quickly, i think this will make the app more of a mess, and not as much maintanable
I think you should reopen user class inside blog_engine in order to define has_many :posts relation and it should be appropriate way.
What about having a common models gem/engine with only the relationships as a dependency for your engines? This way you would have access to all relevant relationships in every engine.

Validations based on session data, sharing data between subdomains

We're building an application for product support. The idea is to have multiple subdomains, each for supporting other organizations products. We call this Account - each account is tied to exactly one subdomain.
Users also have roles - but, user can have one role on account1, and other role on account2.
Basically, there are two problems:
1) many validations are based on the role current user has. Since it depends on current_account (which is session data), I cannot do these kinds of validations in the model. This leads me to some ugly controller code (ugly, in the sense that it really feels out of place). I thought of storing current_account after in the model class variable, but I read that this is not thread safe. Any recommendations?
2) almost every database record is specific to the current account; so, almost every table should have an account_id column and the model should have a belongs_to account association. I want to avoid that. The first (obvious) thing is to have a seperate database for every account, but
a) there are shared tables
b) the boss says this solution is unacceptable (there will be many accounts, with relatively low number of users). Is there a third way?
If anyone runs into similar problem:
The problem described is called multitenancy; understanding default_scope should help. Also, there is the multitenant gem which worked for me nicely.

Resources