Home > Back-end >  Why do Ecto queries need the pin (^) operator?
Why do Ecto queries need the pin (^) operator?

Time:10-18

In a hex.pm project,user.ex file, the get function uses the ^ before the username_or_email variable. Why?

In addition, is fragment part of Etco?

  def get(username_or_email, preload \\ []) do
    from(
      u in Hexpm.Accounts.User,
      where:
        u.username == ^username_or_email or
          ^username_or_email in fragment(
            "SELECT emails.email FROM emails WHERE emails.user_id = ? and emails.verified",
            u.id
          ),
      preload: ^preload
    )
  end

CodePudding user response:

The ^ is called the pin operator and it is used in situations where a variable already has a value, and instead of re-binding the variable (i.e. overwriting it), you want the variable to keep the value it already has. This happens inside pattern matches, e.g.

# binds the value (5) to the variable x
iex> x = 5
5

# If we pin the value of x, the following statement is
# equivalent to `5 = 6`
iex> ^x = 6
** (MatchError) no match of right hand side value: 6

However, the "pins" in Ecto queries have nothing to do with pins in Elixir (see Aleksei's comment): it's just a mnemonic because we want to "pin" a value into the rendered query instead of re-binding a value to the variable. Aleksei has highlighted this in the source code. The takeaway is that when you're dealing with Ecto queries, you need to pin your values.

And yes, Ecto.Query provides a fragment/1 function to help pass SQL fragments directly to the database. It's something like running raw text as a SQL query, but instead of the entire query, fragment/1 lets you generate just fragments of the query.

  • Related