Ruby on Rails 3 single table inheritance or multiple table inheritance? - ruby-on-rails

I'm working on Ruby on Rails 3 application. Already, I have implemented authentication and authorization based on Devise and Cancan. In scope of this I have implemented "Member" object that can have at least 2 different roles - "User" and "Company". Physically, I'd like to represent these roles as two derived classes from Member, such as User and Company.
Should I use single table inheritance or multiple table inheritance. In case of multiple table inheritance what plugin I should use ?

I know it is not the answer to your question but I think you should reconsider using something else than inheritance.
Inheritance is a great OO mechanism but is very often overused. Most often you can do a better job with an association and some kind of Strategy Pattern than with inheritance.
Activerecords are much more compatible with that kind of design than inheritance and it is also much more respecting the Single Responsibility Principle which means it's easier to test in isolation.
If you want to go with the the Strategy pattern in your activerecord model, polymorphic association can be the way to go (this allows you to even have stateful strategies)

Related

DesignPattern for Attachments in a Chat with carrierwave

User should be able to send some pictures to his chat partner (whatsapp/line style).
There might be a possibility to also add other attachments and videos. We having an argue about the model structure. We are using carrierwave to manage the files. right now, the user can only send Pictures, in future there might be some other datatypes to be added.
Solution 1
pretty standard imo, having 3 classes (each has own DB table) and each class is getting his own carrierwave-uploader.
Chat::Picture
Chat::Video
Chat::PDF
Solution 2
this might be a little bit more trickier. Instead of 3 Models we are only having a Chat::Attachment and by that we use STI to define the type.
Chat::Attachment::Picture < Chat::Attachment
Chat::Attachment::Video < Chat::Attachment
Chat::Attachment::Pdf < Chat::Attachment
here also every class is getting his own uploader.
So the Question:: is this the right spot to use STI as a design pattern or should we stick to regular rails-models?
The answer depends on how much change you expect in future. If you expect more changes in future then you should go for rails usual way. I personally dont like STI much. I think you will be better off not using STI here, rails will provide you better separation of concern here. STI should be considered when dealing with model classes that share much of the same functionality and data fields, but you as the developer may want more granular control over extending or adding to each class individually. Rather than duplicate the code over and over for multiple tables (and not being DRY) or forego the flexibility of adding idiosyncratic functionality or methods, STI permits you to use keep your data in a single table while writing specialized functionality.

Sharing AR models between Rails applications

I have a problem that I have been trying to solve for a while now. I have 4 different Rails applications using the same database, meaning they need to use the same models and have the same migrations. I initially solved the problem by creating a Rails engine packaged into a gem, which then carries all the models and migrations with it. Now I realize that there are pieces of functionality that only one application needs, but the others do not - like for example the admin application needs to have methods for providing sortable tables for all models - the other applications do not need this functionality at all.
So my idea was to find a way where I can provide the "base" models from the gem, while augmenting these base models in my specific applications to add additional functionality when needed. What I tried first was inheritance:
class User < Base::User
end
This does not work though, because now you have 2 User models in your load path (User and Base::User) and when querying associations, it always picks the "closest" class for the associated record class - meaning when you have an Model::Account which belongs_to :user, it will pick Model::User as the association class, not User. I tried reversing the AR type compute method but this only resulted in more problems.
I can technically provide all of my models from the base engine (gem), but the issue here is that how do i extend these models in my application? .class_eval feels really really dirty, inheritance does not work, providing base functionality as mixins means the "base" models do not feel and look like models at all. My goal would be to cause as little friction as possible for the other developers, I want them to be able to define their models in the gem like they do normally and then also have an easy way to extend that functionality in other applications.
Has anyone solved this problem before or have any suggestions? Or how do you guys solve this problem in your larger applications? Any help would be appreciated.
This is mentioned in the Rails guides. It describes class modification with the Decorator pattern.

Ruby on Rails: Scope vs Helper Method

I'm pretty new to Rails and wanted to do something along the lines of choosing a subset of objects in my Model. For example, I have a Project model and wanted to select some subset of projects based on some join table with another model, Organizations.
My initial thought was to create some helper method in projects_helper.rb that would perform the appropriate lookup on to determine which projects to return.
Another thought was to utilize scoping as described here (http://apidock.com/rails/ActiveRecord/Scoping/Named/ClassMethods/scope).
Both seem to functionally complete the objective, but what would be the best practice way of accomplishing this? Is there a key difference as to what can access each of these approaches?
Thanks!
Depends on the point of view of the question being "asked" by the query.
If you are asking for an Organization's projects, you might choose the Org first, then display organization.projects. Nothing fancy going on there beyond linking the models appropriately (organization has_many projects, project belongs_to organization) and having the organization_id as a foreign key in the projects table.
I'm not sure if a named scope would be appropriate if the Organizations in your system are a dynamic quantity. You don't want to have a named scope for each if the list of organizations changes all that often.

Namespacing models in a Rails application

I had a discussion recently with a friend of mine who is also a RoR developer. We argued about how Rails models should be managed. Personally I like to leave in the default namespace only the root models (e.g. User, Article, Bill etc.), and the dependent models go to a module (e.g. User::Profile, User::Activity) with the name of the root model they are associated with.
On the other hand, I've seen many projects which had like 100 models in the default namespace called like user_profile, user_activity and so on. Judging by Java (Spring) development, java community tends to organize class in packages and have them grouped logically, which I find very appealing.
So the question is: are there any drawback in grouping models in modules (except the extra :class_name in relation definition) and are there any specific reasons why people usually don't do it?
Although namespacing has its advantages, it does require adding exceptions throughout your models. Foo::Bar presumes a table name of bars and likewise bar_id for associations, whereas you might prefer foo_bars and foo_bar_id to be used instead.
If you really feel strongly about this, you might want to see if there's an add-on that fixes this for you, or implement your own extension that does.
The only case when I've used namespaces is for add-ons that are to be used in third party applications where I don't want to claim root-level model names as that would be annoying. The extra effort in this case is worth-while.
If you're bothered by seeing 100+ model files without any grouping, you'll probably be equally annoyed by seeing 100+ tables with no grouping, and that's generally something you can't fix.
Controllers lend themselves to grouping quite naturally, but models aren't as easily accommodated, at least not with stock ActiveRecord.

Ruby on Rails: What to do when two models share a lot of similar validations/validation_methods

I have a couple of models that are both "password" centric models. They don't belong in a single inheritance table and need to be tracked in separate tables. Logically they are both completely different types of models, but both have password and password confirmation tracking. They also use the same business logic for the password rules such as number of characters in the password etc.
What's the best way in Rails to make sure that the code is DRY and not being repeated in Rails? What should I look into doing?
Factor the common code out into a module, then include the module in each model class.

Resources