You are indeed missing something obvious. Do you know what STI stands for? Single Table Inheritence. You are making several tables and then trying to use STI.
You should only use STI if your tables identical or very similar (maybe 1 field of difference). It is primarily used when you want to subclass and then provide methods to differentiate behaviour. For example, maybe all users share the same attributes but some of them are admins. You can have a type
field in your users table, and then you might have something like this:
class Admin < User
def admin?
true
end
end
class NormalUser < User
def admin?
false
end
end
(this is obviously a very simple example and probably wouldn't warrant STI on it's own).
As far as abstract classes go, that is a good decision if you have several tables that should all inherit behaviour from a super class. It seems like it might make sense in your case; however, it is important to note that abstract classes do not have tables. The whole point of declaring abstract_class
as true is so that ActiveRecord won't get confused when trying to look for a table that doesn't exist. Without it, ActiveRecord will assume you are using STI and try to look for a Questions table. In your case, you do have a question table, so declaring it as an abstract class doesn't really make sense.
One other thing, you ask "Should I be using the module approach instead of inheritance?". Using modules is actually a form of inheritence in Ruby. When you include a module, it is inserted in the classes ancestor chain just like a super class would be (modules are inserted BEFORE super classes however). I do think that some form of inheritance is the correct approach. In this case, because they are both types of questions, making an abstract Question superclass makes sense to me. Because the questions don't share many of their attributes, storing them in separate tables is the best solution in my opinion. STI is not really a good practice when you have several differing fields, because it leads to a lot of null
in your database.
And to be clear about modules, I think that it is best done when several otherwise unrelated models share some form of common behaviour. One example that I've used multiple times is the idea of a Commentable
module (using ActiveSupport::Concern). Just because several models can be commented on doesn't necessarily warrant a superclass because the models are not related - they do not really descend from some sort of parent object. This is where a module makes sense. In your case, a superclass makes sense because both of your models are typed of questions, so it seems appropriate that they both descend from a generic Question
base class.