Coming from Rails

If you know Rails, you already know most of Snails. Routes are declared the same way, controllers answer with JSON instead of views, and models are plain classes over your tables. This chapter is the translation layer for the habits you bring: where routes live now, what replaces Active Record, and which Rails features you will not find here.

What stays the same#

  • Routes live in config/routes.rb and use the same helpers — get, post, put, delete, and resources.
  • Controllers are classes with actions, and parameters arrive on the request object.
  • The database changes the same way: a numbered file under db/migrate/, applied in order, with a snapshot your tests load. See Migrations.
  • A test suite runs with one command: bin/test. See Testing.

What changes#

In Rails In Snails
Views and templates Nothing renders HTML — your app answers with JSON (see Routes and Controllers)
Active Record models Plain model classes over your tables (see Database and Models)
Gemfile and Bundler spin.toml declares what the build needs
A server process you install One native binary that includes the server
Asset pipeline Not needed — there is nothing to compile for the browser
ActionController::Parameters A String-keyed Hash plus ActionController::Params helpers (see Requests and Parameters)
rails generate snails generate, with one generator today: job_queue
rails db:migrate snails migrate apply, with load for first setup
rails test bin/test
perform_later and job callbacks ActiveJob.enqueue, schedule, and recurring; one class-side perform (see Background Jobs)

What is not here#

Some Rails features you may reach for simply do not exist, and that is deliberate:

  • No model callbacks, associations, or validations on the database layer — validation lives in form objects instead (see Forms and Validation).
  • No HTML view helpers, CSRF tokens, sessions, or cookies middleware — the framework is API-only by design. Request cookies are parsed, but there is no session store.
  • No gems in the runtime sense — your app and the framework compile together into one binary.
  • No rescue_from. A controller rescues in an action, or overrides process_action for an app-wide answer (see Error Handling).
  • No ActiveSupport::Concern, included do, or class_methods. A concern is a plain module; write the methods it adds.
  • No before_action inheritance. Registration belongs to the controller class that writes it, not to its subclasses. Declare the filter on each controller that needs it, or share the method through a parent.
  • No class-instance-variable inheritance. A value set on a parent class is not copied to a subclass; use a module constant or an explicit method.

The ActiveSupport surface is deliberately smaller than Rails'. The helpers that do exist are listed in Ruby Helpers; a call to something outside that list fails at build time instead of silently doing nothing.

Where to look next#

When you reach for a Rails feature, the replacement is usually one chapter away:

When the replacement is not there, the FAQ says what is not included, and Troubleshooting covers the errors a Rails habit usually produces.