Core Concepts
Data Modeling

Data Modeling

Use the Rails helper library (opens in a new tab) to generate handy typesafe storage functions for your data model. For example to generate functions for a Todo entity:

import { generate } from "@rocicorp/rails";
 
// Define an entity.
// Must contain id:string.
type Todo = {
  id: string;
  text: string;
  completed: boolean;
  sort: number;
};
 
// Generate common CRUD functions.
export const {
  put: putTodo,
  get: getTodo,
  update: updateTodo,
  delete: deleteTodo,
  list: listTodos,
} = generate<Todo>("todo");

Using Generated Functions

The generated functions can be used directly as simple mutators and subscriptions:

const r = new Reflect({
  mutators: {
    putTodo,
  }
});
 
r.mutate.putTodo({
  id: nanoid(),
  text: "Finish Reflect beta docs",
  completed: false,
  sort: 42,
});
 
r.subscribe(listTodos, ...);

But they can also be composed to create more interesting things:

async function getTodosByCategory(tx: ReadTransaction, category: string) {
  const todos = await listTodos(tx);
  return todos.filter((t) => t.category === category);
}
 
async function setCategoryStatus(
  tx: WriteTransaction,
  arg: { category: string; status: string },
) {
  const { category, status } = arg;
  const todos = await getTodosByCategory(tx, category);
  for (const prev of todos) {
    const next = {
      ...prev,
      status,
    };
    await putTodo(next);
  }
}
 
// ...
 
const r = new Reflect({
  mutators: {
    setCategoryStatus,
  },
});
 
// ...
 
const todos = useSubscribe(r, getTodosByCategory);

Learn More

See the Rails README (opens in a new tab) for more information.