ActiveModel::Naming: what model_name returns

Free preview 3 min to read

Past ActiveModel::Model and attributes

"Form objects: complex logic" covered ActiveModel::Model, ActiveModel::Attributes, and how form_with calls model_name, persisted? and to_key on a plain Ruby object to build a working form. That course treated model_name as one method returning one thing Rails needs. This course picks up there. model_name doesn't return a string. It returns an object, ActiveModel::Name, that carries nine naming values plus a human-readable name, and each one has a job.

The object, field by field

A plain Ruby class with ActiveModel::Model and nothing else:

class ScratchBookCover
  include ActiveModel::Model
end

n = ScratchBookCover.model_name
n.name                # => "ScratchBookCover"
n.singular             # => "scratch_book_cover"
n.plural                # => "scratch_book_covers"
n.element                 # => "scratch_book_cover"
n.collection                # => "scratch_book_covers"
n.route_key                    # => "scratch_book_covers"
n.singular_route_key             # => "scratch_book_cover"
n.param_key                        # => "scratch_book_cover"
n.i18n_key                           # => :scratch_book_cover
n.human                                # => "Scratch book cover"

That's every field, from one call, not a subset picked for the example. Rails' installed source (active_model/naming.rb) computes them all once, in ActiveModel::Name#initialize, and model_name caches the object, so repeat calls return the same one.

Where each one gets used

singular and plural are the underscored base forms the other values build on. element and collection drive partial lookup by convention: to_partial_path returns "#{collection}/#{element}", here scratch_book_covers/scratch_book_cover. param_key is the form-field prefix: form_with(model: cover) generates scratch_book_cover[title] instead of a bare title because of this value. route_key and singular_route_key are what route helpers would be named if this object were routed: scratch_book_covers_path (plural, for index and create) and scratch_book_cover_path (singular, for show and update). i18n_key and human belong to lesson 4: I18n lookup scope and the readable fallback text.

What "Form objects: complex logic" used without naming it

That course showed form_with(model: @form, url: ...) generating correct HTML without saying which of these values did the work. It was param_key all along. Field names like scratch_book_cover[title] come from it, not from Rails inspecting the class name again on every request.

Key takeaways

  • model_name returns an ActiveModel::Name object with nine naming values (name, singular, plural, element, collection, route_key, singular_route_key, param_key, i18n_key) plus human. It's computed once and cached.
  • element and collection drive partial lookup (to_partial_path is collection/element), and param_key is the prefix on every field name form_with generates, the mechanism behind the examples in "Form objects: complex logic".
  • route_key and singular_route_key are the plural and singular forms a route helper would use if this object were routed.
  • i18n_key and human, present on every ActiveModel::Name, are lesson 4's subject: how translations and fallback text are derived.
Lesson 1 of 7 · free

Keep going with lesson 2

route_key, param_key and i18n_key: namespacing changes each differently

On a namespaced class, element drops the module, param_key and route_key flatten it, and i18n_key uses a slash.

A free account also gives you the quizzes, your progress and notes, and the discussion.

Type to start searching...