CRUD
🔥 Hot Tips
- Combine ORM models with routes for instant REST APIs
- Use
response.renderwith templates for server-rendered CRUD - Return
to_hashfrom ORM instances for JSON APIs
JSON API CRUD
Build a full REST API in minutes:
ruby
require "tina4"
class User < Tina4::ORM
integer_field :id, primary_key: true, auto_increment: true
string_field :name
string_field :email
end
# List all
Tina4.get "/api/users" do |request, response|
users = User.all(limit: 50)
response.json(users.map(&:to_hash))
end
# Get one
Tina4.get "/api/users/{id:int}" do |request, response|
user = User.find(request.params["id"])
user ? response.json(user.to_hash) : response.json({ error: "Not found" }, 404)
end
# Create
Tina4.post "/api/users" do |request, response|
user = User.create(request.json_body)
if user.persisted?
response.json(user.to_hash, 201)
else
response.json({ errors: user.errors }, 422)
end
end
# Update
Tina4.put "/api/users/{id:int}" do |request, response|
user = User.find(request.params["id"])
return response.json({ error: "Not found" }, 404) unless user
request.json_body.each { |k, v| user.send("#{k}=", v) if user.respond_to?("#{k}=") }
user.save
response.json(user.to_hash)
end
# Delete
Tina4.delete "/api/users/{id:int}" do |request, response|
user = User.find(request.params["id"])
return response.json({ error: "Not found" }, 404) unless user
user.delete
response.json({ deleted: true })
endTemplate-Based CRUD
Render with Twig templates for server-side HTML:
ruby
Tina4.get "/users" do |request, response|
users = User.all
response.render("users/index.twig", { users: users.map(&:to_hash) })
end
Tina4.get "/users/{id:int}" do |request, response|
user = User.find(request.params["id"])
response.render("users/show.twig", { user: user.to_hash })
endtwig
<!-- templates/users/index.twig -->
{% extends "base.twig" %}
{% block content %}
<table class="table">
<tr><th>ID</th><th>Name</th><th>Email</th></tr>
{% for user in users %}
<tr>
<td>{{ user.id }}</td>
<td>{{ user.name }}</td>
<td>{{ user.email }}</td>
</tr>
{% endfor %}
</table>
{% endblock %}Secured CRUD
Protect write operations with JWT authentication:
ruby
# Public read
Tina4.get "/api/users" do |request, response|
response.json(User.all.map(&:to_hash))
end
# Protected write
Tina4.secure_post "/api/users" do |request, response|
user = User.create(request.json_body)
response.json(user.to_hash, 201)
end
Tina4.secure_delete "/api/users/{id:int}" do |request, response|
User.find(request.params["id"])&.delete
response.json({ deleted: true })
end