Data Model
Type key: data_model_node
Group: Data
Category: data
Tier: CORE
The Data Model node queries any registered Eloquent model with flexible filtering, ordering, and pagination. It is the primary way to read data from your database inside a workflow.
Handles
| Handle | Direction | Description |
|---|---|---|
input | Input | Receives context (used for dynamic filter values) |
output | Output | Emits { "data": [ ...records ] } |
Configuration
| Field | Type | Default | Description |
|---|---|---|---|
model | string | null | Fully-qualified Eloquent model class |
columns | array | ["*"] | Columns to SELECT |
filters | array | [] | WHERE conditions |
order_by | string | null | Column to sort by |
order_direction | enum | asc | Sort direction: asc, desc |
limit | integer | 100 | Maximum records to return |
offset | integer | 0 | Pagination offset |
Model Registration
Only models registered in Voodflow → Model Integrations appear in the selector. To register a model:
- Navigate to Voodflow → Model Integrations
- Click New Integration
- Enter the model class (e.g.
App\Models\Order) and a display label
Filter Configuration
Each filter is an object with:
{
"column": "status",
"operator": "=",
"value": "completed"
}Condition Value Input Modes
In the visual editor, the value field supports two modes:
- Select mode: choose from distinct values fetched from the selected model field
- Manual mode (lightning toggle): type a free value (
4,completed,{{id}}, etc.)
Manual mode is persisted in node configuration, so refreshes do not force the field back to select mode. Distinct values also work with nested relation fields such as customer.name and deeper chains.
Supported Operators
| Operator | Description |
|---|---|
= | Equals |
!= | Not Equals |
> | Greater Than |
< | Less Than |
>= | Greater Than or Equal |
<= | Less Than or Equal |
LIKE | Contains (case-insensitive) |
NOT LIKE | Does Not Contain |
IN | Value is in array (comma-separated string) |
NOT IN | Value is not in array |
BETWEEN | Value is between two values (comma-separated) |
IS NULL | Column is null |
IS NOT NULL | Column is not null |
Dynamic Filter Values
Filter values support {{tags}} for dynamic injection from the execution context:
{
"column": "category_id",
"operator": "=",
"value": "{{input.category}}"
}{
"column": "created_at",
"operator": ">=",
"value": "{{variables.start_date}}"
}Output Format
{
"data": [
{
"id": 1,
"name": "Alice",
"email": "alice@example.com",
"status": "active"
},
{
"id": 2,
"name": "Bob",
"email": "bob@example.com",
"status": "active"
}
],
"count": 2,
"model": "App\\Models\\User",
"limit": 100,
"offset": 0
}Examples
Basic Query: First 10 Users
Model: App\Models\User
Limit: 10
Order: created_at DESCFiltered Query: Completed Orders Over €100
Model: App\Models\Order
Filters:
- status = completed
- total >= 100
Order: created_at DESC
Limit: 500Dynamic Filtering: Orders for a Specific Customer
Model: App\Models\Order
Filters:
- customer_id = {{input.customer_id}}
- status = {{variables.target_status}}Select Specific Columns
Model: App\Models\Product
Columns: id, name, price, stock_qty
Limit: 1000N+1 Prevention
The Data Model node uses Eloquent's query builder, not relationship lazy-loading. All records are fetched in a single query. If you need related data, use the PHP Code node for eager loading, or filter/join via raw expressions.
Notes
- The node executes
Model::query()->where(...)->orderBy(...)->limit(...)->offset(...)->get()->toArray() - Results are automatically converted to arrays (no Eloquent model instances in the pipeline)
- For very large result sets, combine
limitandoffsetwith a For Each + loop pattern to paginate processing