Ecto:where子句是什么(理解语法)
Ecto: What is the where clause (understanding the syntax)
我正在浏览一本 Phoenix Liveview 书,我遇到了这一行:
|> where([d], d.user_id == ^user.id)
我正在尝试理解这种语法。我试着查找 Elixir Guards
但这不是其中之一。这里的 [d]
是什么?这是某种匿名函数吗?
这是在以下地方使用的函数:
def for_user(query \ base(), user) do
query
|> where([d], d.user_id == ^user.id)
end
where
是由ecto
定义的宏。这就是为什么要使用它你需要 import Ecto.Query
,虽然在很多情况下你看不到它,因为你有一个 use MyApp.Schema
或类似的东西,它已经包含了导入。您可以在此处查看文档:Ecto.Query.where docs.
[d]
是宏如何处理给要在 where 子句中使用的记录命名的方式。您可以将名称更改为任何名称,同时更改条件:
query
|> where([a_particular_record], a_particular_record.user_id == ^user.id)
请注意,该宏还覆盖了 ^
的含义 - 在宏内部,它表示“从宏外部注入此值”,这就是为什么您需要在 user.id
之前使用它。
where
是一个接受查询作为第一个参数的宏,returns 是一个查询,因此它可以在管道中使用。管道化许多 where
会导致它们与 AND
组合。如果要将 where 子句与 OR
结合使用,可以使用 or_where
宏。
所以,下面的代码:
query
|> where([user], user.id == ^user.id)
|> where([user], user.name == ^user.name)
将生成如下所示的 SQL 查询:
WHERE user.id = 1 AND user.name = 'somename'
第二个参数是所谓的列表bindings
。在上面的示例中,user
是一个绑定。绑定的工作方式很像 SQL 中的 table 别名,并有效地为您提供了一个变量,用于在整个查询过程中引用您的 table (此描述取自伟大的 Programming Ecto,它给出了深入了解 Ecto 的工作原理和使用方法)。绑定列表可以包含多个元素,以防查询包含连接。使用联接时,绑定应按照指定的顺序进行匹配。
from(user in User)
|> join(:inner, [user], user_settings in assoc(u, :user_settings))
|> where([_user, us], where: us.role == "admin")
绑定变量名称可以不同,但它们指向同一事物。在上面的示例中,join
中的用户设置绑定到 user_settings
变量,但在 where
子句中,它们绑定到 us
变量。
命名绑定也是可能的,它们可以解决一些非命名绑定无法解决的问题,但这里不做描述。更多关于他们的信息可以在 Ecto Documentation.
中找到
where
宏中的最后一个参数是一个必须计算为布尔值的表达式。此表达式包含您要编写的实际 where 子句。
我正在浏览一本 Phoenix Liveview 书,我遇到了这一行:
|> where([d], d.user_id == ^user.id)
我正在尝试理解这种语法。我试着查找 Elixir Guards
但这不是其中之一。这里的 [d]
是什么?这是某种匿名函数吗?
这是在以下地方使用的函数:
def for_user(query \ base(), user) do
query
|> where([d], d.user_id == ^user.id)
end
where
是由ecto
定义的宏。这就是为什么要使用它你需要 import Ecto.Query
,虽然在很多情况下你看不到它,因为你有一个 use MyApp.Schema
或类似的东西,它已经包含了导入。您可以在此处查看文档:Ecto.Query.where docs.
[d]
是宏如何处理给要在 where 子句中使用的记录命名的方式。您可以将名称更改为任何名称,同时更改条件:
query
|> where([a_particular_record], a_particular_record.user_id == ^user.id)
请注意,该宏还覆盖了 ^
的含义 - 在宏内部,它表示“从宏外部注入此值”,这就是为什么您需要在 user.id
之前使用它。
where
是一个接受查询作为第一个参数的宏,returns 是一个查询,因此它可以在管道中使用。管道化许多 where
会导致它们与 AND
组合。如果要将 where 子句与 OR
结合使用,可以使用 or_where
宏。
所以,下面的代码:
query
|> where([user], user.id == ^user.id)
|> where([user], user.name == ^user.name)
将生成如下所示的 SQL 查询:
WHERE user.id = 1 AND user.name = 'somename'
第二个参数是所谓的列表bindings
。在上面的示例中,user
是一个绑定。绑定的工作方式很像 SQL 中的 table 别名,并有效地为您提供了一个变量,用于在整个查询过程中引用您的 table (此描述取自伟大的 Programming Ecto,它给出了深入了解 Ecto 的工作原理和使用方法)。绑定列表可以包含多个元素,以防查询包含连接。使用联接时,绑定应按照指定的顺序进行匹配。
from(user in User)
|> join(:inner, [user], user_settings in assoc(u, :user_settings))
|> where([_user, us], where: us.role == "admin")
绑定变量名称可以不同,但它们指向同一事物。在上面的示例中,join
中的用户设置绑定到 user_settings
变量,但在 where
子句中,它们绑定到 us
变量。
命名绑定也是可能的,它们可以解决一些非命名绑定无法解决的问题,但这里不做描述。更多关于他们的信息可以在 Ecto Documentation.
中找到where
宏中的最后一个参数是一个必须计算为布尔值的表达式。此表达式包含您要编写的实际 where 子句。