Community::Comment: where tone would matter
A model this app already uses for free-form text
app/models/community/comment.rb backs every comment a student leaves on a lesson. Here is the top of the class, without the deleted? helper and the two private validation methods:
module Community
class Comment < ApplicationRecord
MAX_LENGTH = 2_000
belongs_to :user, class_name: "Identity::User"
belongs_to :lesson, class_name: "Catalog::Lesson"
belongs_to :parent, class_name: "Community::Comment", optional: true
has_many :replies, class_name: "Community::Comment", foreign_key: :parent_id, dependent: :destroy
has_rich_text :content
validate :content_present_and_within_limit
validate :single_level_of_replies
scope :visible, -> { where(deleted_at: nil) }
scope :top_level, -> { where(parent_id: nil) }
scope :oldest_first, -> { order(:created_at) }
end
end
Every comment belongs to an Identity::User and a Catalog::Lesson, so the app already knows who wrote a piece of feedback and which lesson it's about. parent is optional and points back at the same table. Threads go one level deep: single_level_of_replies rejects a reply to a reply. Deleting a comment sets deleted_at, and the visible scope filters those rows out instead of destroying them.
Where the text lives, and why a classifier cares
has_rich_text :content means the text isn't a column on community_comments. In db/schema.rb that table holds lesson_id, parent_id, user_id, deleted_at and the two timestamps. The content lives in action_text_rich_texts, one row per comment, in a rich-text body.
Reading it as plain text, for a classifier or anything else, means calling content.to_plain_text. The model's own validation does that already: text = content.present? ? content.to_plain_text.strip : "". MAX_LENGTH caps that plain text at 2,000 characters.
The input a tone classifier would read
Suppose the app wanted an early signal when a student posts a frustrated or confused comment, so an instructor could follow up. Community::Comment#content is the input a sentiment or tone classifier would read. It's free-form text, one comment at a time, already tied to the lesson it's about. That makes it a plausible use for this model, and it's why the course starts here.
What this course does and doesn't do
No lesson in this course runs an AI model against the app's Community::Comment rows. Doing that safely, in a way the course could check and stand behind, is outside what a set of lessons can promise. Every feedback example in the lessons ahead is invented and labeled as invented. The examples are realistic in shape, but none comes from the app's database. Community::Comment sets the scene; it doesn't supply the examples.
What this course covers
Lesson 2 shows that a classifier's output is a category picked from a fixed set. Lesson 3 covers what a confidence score does and doesn't promise. Lesson 4 explains why sarcasm and negation defeat keyword matching, using a tone-dependent case from Anthropic's classification guide. Lesson 5 goes through the gains that guide measures for an LLM classifier. Lesson 6 builds a small, deliberately naive rule-based classifier in plain Ruby, and lesson 7 closes with a graded challenge that implements it.
Keep going with lesson 2
What a classifier outputs: one label from a fixed set
A classifier picks one label from a fixed category set that a person chooses in advance.
A free account also gives you the quizzes, your progress and notes, and the discussion.