怎么做'其中model.field包含数组'在Ecto?

时间:2016-12-21 00:54:45

标签: arrays elixir phoenix-framework ecto

我们假设我的模型的字段sizes是一个数组(例如sizes: ['S', 'M', 'L'])。我想要完成的,构建API,是为了让用户能够根据大小过滤这些模型。所以对此路径发出GET请求:

.../products?sizes=['S','M']

应该返回给定数组是其sizes字段的子数组的所有产品。所以我不想要也不需要完全匹配,但我希望用户能够按照上面的说明进行过滤。我将如何在我的Phoenix API中完成此操作?

我只能完成对包含特定值(where: this in that)的过滤,但是如果我传入一个数组并且我想检查该模型字段中是否包含该数组,那么我就是位丢失。

预先感谢您提供任何帮助,如果您需要任何其他信息,请与我们联系。

修改

我正在尝试使用fragment("? @> ?::varchar[]", p.sizes, ^params["sizes'] )并且它有效,但如果我在现有的基础上添加[color: "red"]这样的简单过滤器,则会失败,这意味着我无法创建一个集合过滤器然后将其添加到where

... and ^filters子句中
filters = Ecto.Changeset.cast(%Product{}, params, [], [:color])
  |> Map.fetch!(:changes)
  |> Map.to_list

# Do I need to actually do this check like this ? (It fails otherwise)
sizes = if is_nil(params["sizes"]) do [] else params["sizes"] end

products_query = from(
  p in Product,
  where: fragment("? @> ?::varchar[]", p.sizes, ^sizes) and
         ^filters
)

这目前无效。

1 个答案:

答案 0 :(得分:4)

正如您已经想到的那样,您需要将@>fragment一起用于“数组包含数组”操作。关于第二个问题,要将where表达式与and链接起来,您只需添加另一个where

products_query = from(
  p in Product,
  where: fragment("? @> ?::varchar[]", p.sizes, ^sizes),
  where: ^filters
)