0

I am attempting to update a existing records in my database using 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

I have a model for %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

When I hit subscribe_email(), an exception is raised:

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

I know that I need to implement to_query() from Ecto.Queryable. However, I do not know how to do this. I am not familiar with Protocols in Elixir, although I have read the official documentation, I have not used Protocols. Please explain how to implement to_query() for my struct.

2 Answers 2

2

That error is a bit misleading. Repo.all doesn't accept a struct with fields filled in like that. You're most likely looking for this:

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

Also, since you're passing the result to Ecto.Changeset.change, you probably want just one record, not a list of all records:

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

Note that this will fail if there's more than one matching record for the query.

Sign up to request clarification or add additional context in comments.

Comments

1

Whilst @Dogbert's answer is the way to go, a couple of other points:

  1. Ecto.Model is deprecated and you should consider moving to Ecto.Schema

  2. If you're curious about protocol implementation look in ./deps/ecto/lib/ecto/repo/queryable.ex - you could, if you're feeling adventurous, quite easily implement what you wrote. But it would be a pain to maintain and difficult for others to read and understand.

1 Comment

Apologies, this should have been a comment, not an answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.