Rails' naming convention, and where this app breaks it
One rule, followed without thinking about it
Every model these courses have touched, like Catalog::Course, Enrollment::Enrollment and Identity::User, finds its table without anyone writing mapping code, most of the time. Rails' rule is to take the class name, demodulize it (drop any Module:: prefix), underscore it and pluralize it. Article becomes articles. That's the whole convention, and it's why no earlier course had to explain it: it works quietly whenever the class name and the table name already agree.
When they stop agreeing
This app's Catalog module defines something most namespaces never bother with:
# app/models/catalog.rb
module Catalog
def self.table_name_prefix
"catalog_"
end
end
That one method changes the convention's output for every model under Catalog::. A throwaway class with no explicit table name:
class Catalog::ScratchNoOverride < ApplicationRecord
end
Catalog::ScratchNoOverride.table_name
# => "catalog_scratch_no_overrides"
The same three steps, demodulize, underscore and pluralize, and then catalog_ in front because the surrounding module asked for it. On its own, Catalog::Course would resolve to catalog_courses. The actual table is courses.
The line that bridges the gap
The first line inside Catalog::Course:
# app/models/catalog/course.rb
class Course < ApplicationRecord
self.table_name = "courses"
end
With that one assignment, the convention's output stops mattering for this class. self.table_name = doesn't adjust the convention; it replaces the result, so Rails never computes catalog_courses for a model that's told which table to use.
Why this matters beyond one model
It isn't a one-off fix for Course. Nearly every model in the Catalog::, Enrollment:: and Partners:: namespaces carries its own self.table_name line: Catalog::Lesson → "lessons", Enrollment::Enrollment → "enrollments", Partners::Partner → "partners". The lines aren't decorative. Without them, each of those classes would look for a prefixed table that doesn't exist, because its namespace defines a table_name_prefix. That's the problem self.table_name solves. The one model that goes without it, Community::Comment, is lesson 2's example.
Key takeaways
- Rails' naming convention: demodulize the class name, underscore it, pluralize it.
Article→articles, with no code written, as long as nothing changes the inputs. - This app's
Catalogmodule definesself.table_name_prefixreturning"catalog_", so a model underCatalog::with no override gets the prefix:catalog_scratch_no_overrides. - That makes the convention's output for
Catalog::Coursecatalog_courses, while the actual table iscourses. self.table_name = "courses", the first line ofCatalog::Course, replaces the computed result instead of adjusting it, and almost every model in the prefixed namespaces carries the same kind of line for the same reason.
Keep going with lesson 2
table_name_prefix: the namespace's default
The table_name_prefix method on namespace modules, and how Community::Comment resolves to community_comments through it.
A free account also gives you the quizzes, your progress and notes, and the discussion.