Models

Models provide an abstraction layer for working with ArangoDB, including CRUD operations and validations.

storage
ArangoDB

Multi-model graph database

check_circle
Validations

Built-in data validation

code
AQL Queries

Powerful query language

architecture Defining Models

Models extend arango_model and define a collection name.

description

Customer Model

app/models/customer.lua

local model = require("arango_model")

local Customer = setmetatable({}, { __index = model })
Customer.__index = Customer
Customer.COLLECTION = "customers"

function Customer.new(data)
  local self = setmetatable(model.new(data), Customer)
  return self
end

return Customer

info Key elements:

check_circle COLLECTION — defines the ArangoDB collection name
check_circle new(data) — constructor that initializes the model
check_circle Inherits CRUD methods from arango_model

sync_alt CRUD Operations

Models provide methods for Create, Read, Update, and Delete operations.

local Customer = require("models/customer")

-- Create
local customer = Customer.new():create({
  name = "John Doe",
  email = "john@example.com"
})

-- Read (via AQL or direct document access)
local doc = Adb.primary:GetDocument(customer._id)

-- Update
Adb.primary:UpdateDocument(customer._id, {
  name = "Jane Doe"
})

-- Delete
Adb.primary:DeleteDocument(customer._id)

verified Validations

Define validations in the model constructor to validate data before saving.

rule

Model with Validations

Define validation rules in new()

function Customer.new(data)
  local self = setmetatable(model.new(data), Customer)

  self.validations = {
    name = { presence = { message = "Name is required" } },
    email = {
      presence = true,
      format = [[^[%w.]+@[%w.]+%.[%w]+$]]
    },
    age = { numericality = { only_integer = true } }
  }

  return self
end

-- Usage
local customer = Customer.new():create({ name = "John" })

if #customer.errors > 0 then
  -- Handle validation errors
  for _, err in ipairs(customer.errors) do
    print(err.field .. ": " .. err.message)
  end
end

Available Validators

presence Field must be present
name = { presence = { message = "Name is required" } }
-- or simply
name = { presence = true }
numericality Value must be a number
price = { numericality = true }
age = { numericality = { only_integer = true, message = "Must be an integer" } }
length String length constraints
code = { length = 10 }                        -- exactly 10 characters
code = { length = { eq = 10 } }               -- exactly 10 characters
name = { length = { minimum = 2 } }           -- at least 2 characters
name = { length = { maximum = 100 } }         -- at most 100 characters
name = { length = { between = { 2, 100 } } }  -- between 2 and 100
format Match a regex pattern
phone = { format = [[^\d+$]] }  -- only digits
inclusion exclusion Value in/not in list
color = { inclusion = { values = { "red", "green", "blue" } } }
status = { exclusion = { values = { "banned", "suspended" } } }
comparaison Compare with another field
password_confirm = { comparaison = "password" }              -- equal
end_date = { comparaison = { gt = "start_date" } }           -- greater than
end_date = { comparaison = { gte = "start_date" } }          -- greater or equal
value = { comparaison = { lt = "max_value" } }               -- less than
value = { comparaison = { lte = "max_value" } }              -- less or equal
username = { comparaison = { other_than = "old_username" } } -- not equal
acceptance Must be true (for checkboxes)
terms = { acceptance = true }

terminal Direct ArangoDB Access

Use Adb.primary for direct database operations.

Method Description
Aql(query) Execute an AQL query
CreateDocument(collection, data) Create a new document
GetDocument(id) Retrieve a document by _id
UpdateDocument(id, data) Update an existing document
DeleteDocument(id) Delete a document
CreateCollection(name) Create a new collection
DeleteCollection(name) Delete a collection
CreateIndex(collection, options) Create an index on a collection
BeginTransaction(options) Start a stream transaction

code AQL Queries

Execute ArangoDB Query Language (AQL) for complex queries.

-- Simple query
local result = Adb.primary:Aql("RETURN UUID()")
local uuid = result.result[1]

-- Query with bind parameters
local customers = Adb.primary:Aql([[
  FOR c IN customers
    FILTER c.status == @status
    SORT c.created_at DESC
    LIMIT @limit
    RETURN c
]], { status = "active", limit = 10 })

-- Handle results
for _, customer in ipairs(customers.result) do
  print(customer.name)
end

-- Error handling
if customers.error then
  print("Error: " .. customers.errorMessage)
end

sync Transactions

Use transactions for atomic operations across multiple documents.

Stream Transactions

-- Begin transaction
local tx = Adb.primary:BeginTransaction({
  collections = {
    write = { "orders", "inventory" }
  }
})

-- Perform operations...

-- Commit or abort
Adb.primary:CommitTransaction(tx.result.id)
-- or
Adb.primary:AbortTransaction(tx.result.id)

JavaScript Transactions

local result = Adb.primary:Transaction({
  collections = {
    read = "customers"
  },
  action = [[
    function() {
      // JavaScript code here
      return db.customers.count();
    }
  ]]
})
lightbulb

Pro Tips

Indexes: Create indexes on frequently queried fields to improve performance.

Validations: Always validate user input before saving to prevent bad data.

AQL: Use bind parameters (@param) instead of string concatenation to prevent injection attacks.