Skip to content

Consider adding a helpful message for #find(arg) when arg is nilable #1079

@robacarp

Description

@robacarp

Today I wrote a Task that took a model ID as an argument, and passed that to a Query.find() and was greeted with a rather misdirecting error. I had to open up the query builder and comment out the line that generates this error message to find the problem.

The root of the problem is that find() cannot take a nilable, but that seems like it'd be easy to add a typed overload to that causes it to emit a more helpful error message.

Here's the error I got:

In cli:14:19

 14 | LuckyTask::Runner.run
                        ^--
Error: 

The 'eq' method can't compare a column to a value that may be 'nil'.

▸ If you didn't realize the value might be nil...

    # Try using an if/case to conditionally add wheres to your query
    query = MyQuery.new
    name = name_that_might_be_nil

    if name
      # We can be sure value is not nil and can safely use it
      query.name(name)
    else
      # Don't add the name criteria, give me all users if 'name' is nil
      query
    end

▸ If you want to allow comparing to 'nil'...

    # Use 'nilable_eq' to allow querying against nil.
    #
    # For example if you have an optional 'nickname' column and you want
    # to allow people to query it with a String to find people with a
    # nickname, or Nil to find people without a nickname:
    UserQuery.new.nickname.nilable_eq(nickname_that_can_be_nil)

▸ If the compiler is wrong and the value can't be 'nil'...

    # Use 'not_nil!' to tell Crystal that the value won't actually be 'nil'
    # When using this, be careful that the value really won't be 'nil'
    # or you will get a runtime error
    UserQuery.new.name(name_that_isnt_actually_nil.not_nil!)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions