Create your models

You have tables, but no way to talk to them yet. You could scatter database calls across every route file, but that gets messy fast. A model wraps a table and gives you simple methods — Form.create(data), Form.findByID(id), Form.delete(id) — so each table has one place that handles its operations.

The model factory

Your starter includes an app/models/.server/base/ folder with files for queries, types, and error handling. Together they export a createModel function that takes a table and returns an object with methods (functions attached to an object) like create, findBy, update, and delete. You don't need to dig into those files — just know that they handle the database calls for you.

Here's what each method does:

MethodWhat it does
create(data)Insert a new row
findByID(id)Get one row by its ID
findBy({ column: value })Get one row where column = value
newest() / oldest()Get all rows, newest or oldest first
update(id, data)Update a row by ID
delete(id)Delete a row by ID
?Table conventions in Gista.js

These are the same basic operations every table needs. Instead of writing raw database queries in every route, you call Form.create() or Submission.newest() and the model handles the rest.

Create the models

Ask your AI:

Create two model files. `app/models/.server/form.ts` should create a base with `createModel(forms)`, then export `Form` by spreading the base into a new object. `app/models/.server/submission.ts` should do the same with `createModel(submissions)`. Import the tables from the schema file.

The models should look like this:

app/models/.server/form.ts
import { createModel } from './base'
import { forms } from '~/.server/db/schema'

const base = createModel(forms)

export const Form = { ...base }
app/models/.server/submission.ts
import { createModel } from './base'
import { submissions } from '~/.server/db/schema'

const base = createModel(submissions)

export const Submission = { ...base }

Simple. The ...base copies all the built-in methods into your model object. You don't need to understand this syntax yet — just know that Form and Submission now have all the methods from the table above, and you can add your own later.

Route → Model → Database

Here's the flow that you'll use from now on:

  1. Route receives a request (a page load or a form submission)
  2. Model handles the data operation (Form.create(), Submission.newest())
  3. Database stores and retrieves the actual rows

The route doesn't talk to the database directly. The model is the middleman — it keeps your routes clean and your database logic in one place.

?What is a model?