abstract struct Interro::QueryBuilder(T)
- Interro::QueryBuilder(T)
- Struct
- Value
- Object
Overview
Defining QueryBuilder
objects is a way to create composable queries. For
example, if you have the following Model
and QueryBuilder
:
struct User
include Interro::Model
getter id : UUID
getter name : String
getter email : String
getter team_id : UUID?
getter role : Role
enum Role
Member
TeamAdmin
SiteAdmin
end
end
struct UserQuery < Interro::QueryBuilder(User)
table "users"
def find(id : UUID)
where(id: id).first?
end
def on_team(team : Team)
where team_id: team.id
end
def with_role(role : User::Role)
# We pass `role.value` to the SQL query since it's stored in `INTEGER`
# column type.
where role: role.value
end
def sorted_by_name(direction : Interro::QueryBuilder::OrderByDirection = :asc)
order_by name: direction
end
end
Then you can find all team admins like this:
users = UserQuery.new
.on_team(team)
.with_role(:team_admin)
.sorted_by_name
You can insert records with the insert
method:
struct UserQuery < Interro::QueryBuilder(User)
# ...
def create(name : String, email : String, team : Team, role : User::Role)
# This generates the following SQL:
# INSERT INTO users (name, email, team_id, role) VALUES ($1, $2, $3, $4)
# And it passes these args to the parameterized query:
# [name, email, team.id, role.value]
insert(
name: name,
email: email,
team_id: team.id,
role: role.value,
)
end
end
You can also use Interro::Validations::Result
objects to validate the
inputs before saving them to the DB. Since Interro::QueryBuilder
includes
the Interro::Validations
mixin, you can simply refer to it as Result
.
struct UserQuery < Interro::QueryBuilder(User)
# ...
def create(name : String, email : String, team : Team, role : User::Role)
Result(User).new
.validate_presence(name: name, email: email)
.validate_uniqueness("email") { where(email: email).any? }
.valid do
insert(
name: name,
email: email,
team_id: team.id,
role: role.value,
)
end
end
end
Included Modules
- Enumerable(T)
- Interro::Validations
- Iterable(T)
Direct Known Subclasses
Defined in:
dynamic_query.crquery_builder.cr
Constructors
Macro Summary
Instance Method Summary
- #&(other : self) : CompoundQuery
- #-(other : self) : CompoundQuery
- #|(other : self) : CompoundQuery
-
#any? : Bool
Returns
true
if at least one of the collection's members is truthy. - #count : Int64
-
#each
Must return an
Iterator
over the elements in this collection. -
#each(& : T -> )
Must yield this collection's elements to the block.
-
#first(count : Int)
Returns an
Array
with the first count elements in the collection. -
#first
Returns the first element in the collection.
-
#first?
Returns the first element in the collection.
- #initialize
- #merge(other : QueryBuilder) : self
- #to_json(json : JSON::Builder) : Nil
- #to_sql : String
Constructor Detail
Macro Detail
Instance Method Detail
Returns true
if at least one of the collection's members is truthy.
[nil, true, 99].any? # => true
[nil, false].any? # => false
([] of Int32).any? # => false
#present?
does not consider truthiness of elements.#any?(&)
and#any(pattern)
allow custom conditions.
NOTE #any?
usually has the same semantics as #present?
. They only
differ if the element type can be falsey (i.e. T <= Nil || T <= Pointer || T <= Bool
).
It's typically advised to prefer #present?
unless these specific truthiness
semantics are required.
Must return an Iterator
over the elements in this collection.
Must yield this collection's elements to the block.
Returns an Array
with the first count elements in the collection.
If count is bigger than the number of elements in the collection, returns as many as possible. This include the case of calling it over an empty collection, in which case it returns an empty array.
Returns the first element in the collection. Raises Enumerable::EmptyError
if the collection is empty.
([1, 2, 3]).first # => 1
([] of Int32).first # raises Enumerable::EmptyError
Returns the first element in the collection.
When the collection is empty, returns nil
.
([1, 2, 3]).first? # => 1
([] of Int32).first? # => nil