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.
Whilst @Dogbert's answer is the way to go, a couple of other points:
Ecto.Model
is deprecated and you should consider moving toEcto.Schema
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.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:Also, since you're passing the result to
Ecto.Changeset.change
, you probably want just one record, not a list of all records:Note that this will fail if there's more than one matching record for the query.