Skip to content

Class and Path String Transformations

Loci includes Active Support core string helpers and extends them with a few additional helpers of its own. This means methods like pluralize, singularize, and camelize are already available, and Loci adds higher-level helpers focused on paths, namespaces, and class names.

Together, these helpers make string transformations predictable and readable, especially when working with frameworks like Rails.

This tutorial walks through a real example based on Rails resource naming conventions.

The Problem We Want to Solve

Rails naming usually follows a few simple rules:

  • Resources can live in a namespace
  • Controllers use plural names and end with Controller
  • Models use singular names and no suffix
  • File paths and class names must stay in sync

Starting Point

Assume a generator with a single argument:

ruby
arg :name

Executed like this:

bash
loci g controller api/v1/user
ruby
params.name
# => "api/v1/user"

Extracting Namespace and Filename

Loci strings understand namespaces and filenames.

ruby
namespace = params.name.namespace
# => "api/v1"

filename = params.name.filename
# => "user"

Building the Controller Name

Rails controllers:

  • Use plural form
  • End with _controller
ruby
controller_name = filename.pluralize.suffix("_controller")
# => "users_controller"

The suffix helper only adds the suffix if it is missing:

ruby
"users".suffix("_controller")
# => "users_controller"

"users_controller".suffix("_controller")
# => "users_controller"

Building the Model Name

Rails models:

  • Use singular form
  • Have no suffix
ruby
model_name = filename.singularize
# => "user"

Constructing Paths

Controller Path

ruby
controllers_path = "app/controllers"

controller_path =
  controllers_path
    .join(namespace, controller_name)
    .ext("rb")
    .to_path

# => "app/controllers/api/v1/users_controller.rb"

Model Path

ruby
models_path = "app/models"

model_path =
  models_path
    .join(namespace, model_name)
    .ext("rb")
    .to_path

# => "app/models/user.rb"

Constructing Class Names

Controller Class

ruby
controller_class =
  namespace
    .join(controller_name)
    .to_class

# => "Api::V1::UsersController"

Model Class

ruby
model_class =
  namespace
    .join(model_name)
    .to_class

# => "Api::V1::User"