I don't think there is a simple explanation why any approach is the best in any circumstance. A significant amount of questions on Stack Overflow are question on how to design relations between their models. It's a complicated topic and the right solutions require intimate knowledge of the problem you are solving. And even then, you probably won't get it right the first couple of times.
The best way so far is to completely work TDD/BDD on this matter and let the tests/specs drive out your design. And don't be afraid to refactor is you find a better way. Most of the time you will only see the right solution after you've tried a couple of wrong ones. You'll get to know the edge cases. As Ward Cunningham puts it in his "Technical Debt" analogy: "Refactor afterwards as if you knew what you were doing from the start". Be sure to have the acceptance tests to verify its behavior afterwards though.
Getting more specific to your problem. There is a third option and that is to completely split up the classes, each with their own table. I've tried it in my current project and I like it. You don't need to define something like a user, if that doesn't make sense in your business domain. If they have shared behavior, use mixins. The most important caveat is that it's not straight forward to have them login through the same form anymore.
I have Admin, Recruiter, Supplier and Visistor models. They are all separate models, sharing some behavior with mixins. They all have their own namespaced controllers to act on. For instance, all actions for the admins are in the Backend namespace. There is a namespaced ApplicationController too. The Backend::ApplicationController simply specifies before_filter :authorize_admin!. No switching, no complicated case statements, nothing.
You need to pay special attention to conventions. If you use the same names across the models, your mixins can become super easy. Read up on ActiveSupport::Concern to make mixins even easier to work with. I have a mixin like this:
And in my routes:
So, to conclude. Any architecture will work. STI and polymorphism have their place, but be sure to model your architecture according to your domain. Ruby is a very flexible language and you can use this to your advantage. Devise and CanCan are excellent gems and can handle these situations with ease. I showed you my solution for a project I'm currently working on. It works well for me, but I cannot say if it works right for you. Don't be afraid to experiment and refactor when you feel you've made a bad decision, rather than keep patching up your original idea.
PS. Speaking of STI and relations: they work excellent together too. You can define relations from one subclass to another subclasses. It will all work as expected.
I read several other articles referencing Modules and mixins, yet I don't have any idea what they are. Is there a good resource online that you know of where I can read up on what they are and how to use them? I couldn't glean much from the official Rails docs...
Modules aren't Rails specific, so they are not actively mentioned in the Rails docs. Any documentation on Ruby metaprogramming will mention them extensively, because they are an important part of Ruby. I learned the most from Dave Thomas' screencasts. Not only good for learning Ruby, but learning OO in general.
I've been reading up on Modules and mixins--courtesy of the Picaxe book--but all the examples I've found thus far talk about Modules and mixins in a pure Ruby environment, not within Rails. Where do I define Modules in Rails?