2017-03-16 4 views
1

나는 phoenix를 JSON API로 사용하고 있습니다. 내 모델 중 하나는 unique_constraint 검사가 실패하지 않는 한 잘 작동하는 다음과 같습니다.포이즌이 오류 메시지를 인코딩 할 수 없습니다.

(Poison.EncodeError) unable to encode value: {"Email address is already registered", []} 

모델 :

defmodule MyApp.Registration do 
    use MyApp.Web, :model 

    @derive {Poison.Encoder, only: [:name, :email, :category]} 
    schema "registrations" do 
    field :name, :string 
    field :category, :string 
    field :email, :string 

    timestamps 
    end 

    def changeset(model, params \\ :empty) do 
    model 
    |> cast(params, ~w(name email category), []) 
    |> validate_length(:name, min: 1, max: 240) 
    |> unique_constraint(:email, message: "Email address is already registered") 
    end 

end 

컨트롤러 :

def create(conn, registration_params) do 
    changeset = Registration.changeset(%Registration{}, registration_params) 
    case Repo.insert(changeset) do 
    {:ok, _registration} -> 
     # Success 
    {:error, error} -> 
     conn 
     |> put_status(:unprocessable_entity) 
     |> render(MyApp.ErrorView, "generic.json", error: error) 
    end 
end 

보기 :

그렇게되면 나는 다음과 같은 오류가 발생합니다

나는 아마도 어떻게 든 Poison.Encoder, only: [] 목록에 오류 메시지를 추가해야한다고 생각하지만 그 방법을 확신하지 못합니다.

편집

나는 사용자 지정 오류를 지정하지 않은 경우, 나는 여전히 일반 오류 메시지와 같은 오류가 있음을 명확히해야한다.

+0

오류는 Ecto.Changeset 아니라 모델의 일부입니다. json을 렌더링하는 컨트롤러 코드와 가능한 뷰 코드를 제공 할 수 있습니까? – Svilen

+0

@Svilen 컨트롤러와 뷰 코드를 추가했습니다. 변경 세트 오류를 ​​json 뷰에 전달하는 몇 가지 방법을 시도했지만 지금까지는 기쁨이 없습니다. – Razzildinho

답변

3

mix phoenix.gen.json을 사용하는 경우 자동으로 수행되지만 변경 세트 오류는 json으로 변환되어야한다고 생각합니다.

보기 :

def translate_errors(changeset) do 
    Ecto.Changeset.traverse_errors(changeset, &translate_error/1) 
end 

def render("error.json", %{changeset: changeset}) do 
    # When encoded, the changeset returns its errors 
    # as a JSON object. So we just pass it forward. 
    %{errors: translate_errors(changeset)} 
end 

컨트롤러 :

def create(conn, registration_params) do 
    changeset = Registration.changeset(%Registration{}, registration_params) 
    case Repo.insert(changeset) do 
    {:ok, _registration} -> 
     # Success 
    {:error, changeset} -> 
     conn 
     |> put_status(:unprocessable_entity) 
     |> render(MyApp.ErrorView, "error.json", changeset: changeset) 
    end 
end 

편집

translate_error\1 함수 정의를 추가. 이 모듈은 MyApp.ErrorHelpers 모듈에 포함되어 있으며또는 lib/my_app_web.ex에있는 view 함수 정의로 가져 오며 피닉스 버전에 따라 다릅니다.

lib/my_app_web/views/error_helpers.ex

: 그 이상한 보이는 있도록

defmodule MyAppWeb.ErrorHelpers do 
    def translate_error({msg, opts}) do 
    if count = opts[:count] do 
     Gettext.dngettext(MyAppWeb.Gettext, "errors", msg, msg, count, opts) 
    else 
     Gettext.dgettext(MyAppWeb.Gettext, "errors", msg, opts) 
    end 
    end 
end 
+0

'translate_error/1' 함수는 어디에서 정의 되었습니까? –

+0

@ Jean-PierreBécotte 함수 정의로 대답을 업데이트했습니다. – Razzildinho

+0

좋은 직장, @Razzildinho! –