supabase-rb-rb
Database

Retrieve zero or one rows

Expect 0 or 1 row. Returns nil on no match; raises only when more than 1 row comes back.

Soft variant of single. Lives on the select builder. Unlike single, the SELECT-chain maybe_single does not set the vnd.pgrst.object+json Accept header — the request goes out expecting an array, and the client inspects the result:

  • 0 rows → .execute returns nil (not a response object).
  • 1 row → .execute returns a SingleAPIResponse with the row as a Hash.
  • more than 1 row → raises Supabase::Postgrest::Errors::APIError with the message "Cannot coerce the result to a single JSON object".

Pick maybe_single whenever "no row" is a valid case in your domain — it's the friendlier shape for optional lookups.

Signature

builder.maybe_single

Parameters

This method has no parameters.

Returns

Returns
Supabase::Postgrest::MaybeSingleRequestBuilder

A builder that, when .execute'd, returns nil (no row), a SingleAPIResponse (one row, data is a Hash), or raises an APIError (more than one row).

Example — optional lookup

response = supabase
  .from("users")
  .select("id, email")
  .eq("email", "alice@example.com")
  .maybe_single
  .execute

if response.nil?
  puts "no such user"
else
  response.data  # => { "id" => 7, "email" => "alice@example.com" }
end

Example — guard a >1 accident

If multiple rows match (the filter is not unique), .execute raises:

begin
  supabase
    .from("countries")
    .select("*")
    .eq("continent", "Africa")  # many rows
    .maybe_single
    .execute
rescue Supabase::Postgrest::Errors::APIError => e
  e.message  # => "Cannot coerce the result to a single JSON object"
end

If you don't want any >1 guard, drop maybe_single and call .execute directly — you'll get the array of rows.

maybe_single vs single

maybe_singlesingle
Sets Accept: application/vnd.pgrst.object+jsonno (SELECT chain)yes
0 rows.execute returns nil (no exception)raises APIError (PGRST116)
1 rowdata is the row as a Hashdata is the row as a Hash
more than 1 rowraises APIError ("Cannot coerce…") — client-side checkraises APIError (PGRST116) — server-side
Use whenthe row may or may not exist (optional lookup)the row must exist (PK lookup)

The single most user-visible difference: with single, a missing row is an exception you must rescue; with maybe_single, it's a nil you can branch on.

maybe_single does not set the object Accept header on SELECT chains

The SELECT-chain maybe_single deliberately omits the vnd.pgrst.object+json Accept header (the RPC variant does set it). This asymmetry is intentional — not a bug.

On this page