I\'m pretty familiar with when to use subclasses and modules, but more recently I\'ve been seeing nested classes like this:
class Foo
class Bar
# do so
There is yet another difference between nested classes and nested modules in Ruby prior to 2.5 that other answers failed to cover that I feel must be mentioned here. It is the lookup process.
In short: due to top level constant lookup in Ruby prior to 2.5, Ruby may end up looking for your nested class in the wrong place (in Object in particular) if you use nested classes.
In Ruby prior to 2.5:
Nested class structure:
Suppose you have a class X, with nested class Y, or X::Y. And then you have a top level class named also Y. If X::Y is not loaded, then following happens when you call X::Y:
Having not found Y in X, Ruby will try to look it up in ancestors of X. Since X is a class and not a module, it has ancestors, among which are [Object, Kernel, BasicObject]. So, it tries to look for Y in Object, where it finds it successfully.
Yet it is the top level Y and not X::Y.
You will get this warning:
warning: toplevel constant Y referenced by X::Y
Nested module structure:
Suppose in the previous example X is a module and not a class.
A module only has itself as ancestor: X.ancestors would produce [X].
In this case, Ruby won't be able to look for Y in one of ancestors of X and will throw a NameError. Rails (or any other framework with autoloading) will try to load X::Y after that.
See this article for more information: https://blog.jetbrains.com/ruby/2017/03/why-you-should-not-use-a-class-as-a-namespace-in-rails-applications/
In Ruby 2.5:
Top level constant lookup removed.
You may use nested classes without fear of encountering this bug.