【问题标题】:How to implement to_query(data) in Elixir Struct如何在 Elixir Struct 中实现 to_query(data)
【发布时间】:2016-12-30 23:55:00
【问题描述】:

我正在尝试使用 Repo.update 更新我的数据库中的现有记录:

  def subscribe_email(conn, %{"email-address"=>email_address, "shop"=>shop}) do
    current_record = Repo.all(%Oauth.EmailAddress{email_address: email_address, active: false, shop: shop, verified: :true})
    current_record = Ecto.Changeset.change(current_record, active: :true)
    case Repo.update current_record do
      {:ok, struct} -> IO.puts "updated correctly."
      {:error, changeset} -> IO.puts "did not update"
    end
  end

我有一个 %Oauth.EmailAddress 的模型:

defmodule Oauth.EmailAddress do
  use Ecto.Model

  schema "email_address" do
    field :email_address, :string
    field :active, :boolean
    field :shop, :string
    field :verified, :boolean
    timestamps
  end
end

当我点击 subscribe_email() 时,会引发异常:

** (Protocol.UndefinedError) protocol Ecto.Queryable not implemented   for %Oauth.EmailAddress

我知道我需要从 Ecto.Queryable 实现 to_query()。但是,我不知道如何 这样做。我对 Elixir 中的 Protocols 不熟悉,虽然我看过官方文档,但我没有使用过 Protocols。请解释如何为我的结构实现 to_query()。

【问题讨论】:

    标签: elixir phoenix-framework ecto


    【解决方案1】:

    这个错误有点误导。 Repo.all 不接受这样填写字段的结构。你最有可能在寻找这个:

    current_record =
      from(Oauth.EmailAddress)
      |> where(email_address: email_address, active: false, shop: shop, verified: :true)
      |> Repo.all
    

    另外,由于您将结果传递给Ecto.Changeset.change,您可能只需要一条记录,而不是所有记录的列表:

    current_record =
      from(Oauth.EmailAddress)
      |> where(email_address: email_address, active: false, shop: shop, verified: :true)
      |> Repo.one
    

    请注意,如果查询有多个匹配记录,这将失败。

    【讨论】:

      【解决方案2】:

      虽然@Dogbert 的回答是要走的路,但还有几点:

      1. Ecto.Model 已弃用,您应该考虑转移到 Ecto.Schema

      2. 如果您对协议实现感到好奇,请查看./deps/ecto/lib/ecto/repo/queryable.ex - 如果您喜欢冒险,您可以很容易地实现您编写的内容。但是维护起来很痛苦,其他人也很难阅读和理解。

      【讨论】:

      • 抱歉,这应该是评论,而不是答案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多