Query Builder¶
The Rubik ORM Query Builder provides a fluent, driver-aware API to construct and execute SQL queries programmatically — while still giving you full control over the final SQL.
It supports:
SELECT
,UPDATE
, andDELETE
operations- Conditions, joins, grouping, ordering, and pagination
- Automatic hydration into model instances
Rubik’s query builder is intentionally minimal, predictable, and close to SQL, without hiding what’s really happening.
🧩 Creating Queries¶
Each model comes with a static query()
method that returns a Query
instance bound to that model:
Alternatively, you can manually create a new builder:
🎯 Selecting Data¶
The simplest way to retrieve data:
You can specify selected fields:
If you omit
.select()
, Rubik defaults toSELECT *
.
You can also get only the first record:
Or fetch by primary key (shortcut):
🔍 Filtering with where
¶
Rubik provides fluent where()
and orWhere()
methods.
Examples¶
// Simple equals
User::query()->where('id', 1)->first();
// Custom operator
User::query()->where('age', '>=', 18)->all();
// Multiple conditions
User::query()
->where('country', 'Brazil')
->orWhere('country', 'Portugal')
->all();
Each call adds a condition with its conjunction (AND
or OR
).
Supported operators: =
, <>
, <
, >
, <=
, >=
, LIKE
.
🧰 WHERE IN¶
Filter values with whereIn()
:
Rubik handles placeholder binding safely under the hood.
🧮 Ordering, Grouping, and Having¶
Order results:
Group and filter aggregates:
User::query()
->select(['country', 'COUNT(*) AS total'])
->groupBy('country')
->having('COUNT(*) > 10')
->orderBy('total', 'DESC')
->all();
🔗 Joins¶
Rubik supports INNER JOIN
, LEFT JOIN
, and RIGHT JOIN
:
User::query()
->join('posts', 'users.id', '=', 'posts.user_id')
->select(['users.name', 'posts.title'])
->all();
Available join methods¶
Method | Description |
---|---|
join($table, $left, $op, $right) |
Standard INNER JOIN |
leftJoin($table, $left, $op, $right) |
LEFT JOIN |
rightJoin($table, $left, $op, $right) |
RIGHT JOIN |
💡 You can chain multiple joins for complex queries.
🧾 Limits and Offsets¶
Limit and offset your results easily:
🧭 Pagination¶
Use paginate()
to get structured pagination data:
$paginated = User::query()
->where('country', 'Brazil')
->orderBy('id')
->paginate(page: 2, perPage: 5);
print_r($paginated);
Output:
[
'data' => [ ... array of User models ... ],
'total' => 43,
'per_page' => 5,
'current_page' => 2,
'last_page' => 9
]
Pagination automatically uses COUNT(*)
internally.
✏️ Updating Records¶
Perform updates directly via the builder:
Returns
true
if successful, or throws an exception on error.
Or use the model API instead:
🗑️ Deleting Records¶
Delete records via the builder:
Or delete via the model API:
🧪 Counting Records¶
Count results matching your filters:
⚙️ Building SQL Strings¶
You can inspect the raw SQL generated by the builder:
Example output:
Rubik safely binds parameters, but you can preview SQL to debug complex queries.
🧩 Model Hydration¶
When using a model-bound query (User::query()
), Rubik hydrates each record into a model instance:
Each hydrated model supports full ORM features:
save()
delete()
toArray()
- Relationships (
hasMany
,belongsTo
, etc.)
If you use the builder without a model:
then results are returned as plain associative arrays instead.
💾 Executing Arbitrary Queries¶
You can run any SQL using Rubik’s connection:
$conn = AdaiasMagdiel\Rubik\Rubik::getConn();
$stmt = $conn->query('SELECT COUNT(*) AS total FROM users');
$total = $stmt->fetchColumn();
Rubik doesn’t restrict direct SQL — the Query Builder is optional for convenience.
🧠 Error Handling¶
Rubik throws RuntimeException
or InvalidArgumentException
on:
- Invalid SQL operations
- Missing table or driver
- Incorrect operators
- Invalid pagination parameters
You can safely wrap builder calls in try/catch
blocks:
try {
$users = User::query()->where('id', '>', 10)->all();
} catch (RuntimeException $e) {
echo "Query failed: " . $e->getMessage();
}
🧾 Summary of Query Methods¶
Method | Description |
---|---|
select($fields) |
Specify columns to select |
where($key, $operatorOrValue, $value = null) |
Add a WHERE condition |
orWhere($key, $operatorOrValue, $value = null) |
Add an OR condition |
whereIn($key, array $values) |
Add a WHERE IN condition |
join($table, $left, $op, $right) |
Add an INNER JOIN |
leftJoin($table, $left, $op, $right) |
Add a LEFT JOIN |
rightJoin($table, $left, $op, $right) |
Add a RIGHT JOIN |
orderBy($column, $direction) |
Sort results |
groupBy($column) |
Group results |
having($condition) |
Filter aggregates |
limit($n) |
Limit results |
offset($n) |
Skip results |
count() |
Count total records |
paginate($page, $perPage) |
Paginate results |
update($data) |
Update records |
delete() |
Delete records |
getSql() |
Return raw SQL string |
first() |
Return first record |
all() |
Return all records |
🧭 Next Steps¶
- Models — Learn how models integrate with queries
- Relationships — Load related data elegantly