2016-08-24 58 views
0

我試圖更新我的數據庫中的現有記錄Repo.update:如何使用來實現to_query(數據)花好月圓結構

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.Q to_query() ueryable。但是,我不知道如何來做到這一點。我不熟悉Elixir中的Protocols,儘管我已閱讀官方文檔,但我沒有使用Protocols。請解釋如何爲我的結構實現to_query()。

回答

2

該錯誤有點令人誤解。 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 

注如果查詢有多個匹配記錄,則這會失敗。

1

雖然@ Dogbert的答案是要走的路,其他幾個點:

  1. Ecto.Model已經過時,你應該考慮遷移到Ecto.Schema

  2. 如果您想了解協議的實現看看./deps/ecto/lib/ecto/repo/queryable.ex - 如果你喜歡冒險,可以很容易地實現你寫的東西。但是,維護並且難以讓其他人閱讀和理解將是一種痛苦。

+0

道歉,這應該是一個評論,而不是答案 – Kip