Calcul de la valeur des champs virtuels avec DecorateX

voix
0

Je suis en train d'utiliser la Decoratex bibliothèque pour remplir certains champs virtuels dans mon modèle d'utilisateur , mais je suis incapable d'éviter l'erreur suivante:

no function clause matching in Decoratex.decorate/1
  This functions just call the configured function to each field passing
  the model structure it self and it store the result in the virtual field.
  
  @spec decorate(nil) :: nil
  def decorate(nil), do: nil
  @spec decorate(struct) :: struct
  def decorate(%module{} = element) do
    module.__decorations__ |> Enum.reduce(element, &do_decorate/2)
  end

À titre d'exemple, je suis en train d'ajouter une valeur clé user_age à la struct modèle. Le modèle est le suivant:

defmodule InformAPI.UTL.User_take_list do
  use Ecto.Schema
  use Decoratex.Schema
  # alias InformAPI.UTL.UTLHelpers


  import Ecto.Changeset

  decorations do
    decorate_field :user_age, :integer,  &UTLHelpers.calculate_user_age/1

  end


  schema user_take_lists do
    field :date_of_birth, :date
    field :first_name, :string
    field :last_name, :string
    field :user_id, :string
    field :needs_senior_review, :boolean
    field :stable, :boolean
    field :list_date, :date
    belongs_to :consultant, InformAPI.UTL.User_take_list_consultant

timestamps()
decorations()
end


  def changeset(user_take_list, attrs) do
    user_take_list
    |> cast(attrs, [:user_id, :first_name, :date_of_birth, :last_name, :needs_senior_review, :list_date, :stable, :consultant_id])
    |> validate_required([:user_id, :first_name, :date_of_birth, :last_name, :needs_senior_review, :consultant_id, :stable])
  end
end

La fonction calculate_user_age est actuellement configuré pour revenir juste un résultat:

defmodule InformAPI.UTL.UTLHelpers do
  alias InformAPI.UTL.User_take_list

  def calculate_user_age(struct) do
    x = [1,2,3,4,5,6]
    Enum.count(x)
  end
end

Et le Decoratex.decorate nécessaire est appelée la fonction Index de mon contrôleur:

defmodule InformAPIWeb.User_take_listController do
  import Ecto.Query, warn: false
  use InformAPIWeb, :controller
  use Filterable.Phoenix.Controller

  alias InformAPI.UTL
  alias InformAPI.UTL.User_take_list
  alias InformAPI.Repo

  action_fallback InformAPIWeb.FallbackController

  filterable do
    filter review(query, value, _conn) do
      IO.inspect(query)
      query |> where(needs_senior_review: ^value)
    end

    @options param: :dateFrom, cast: :date 
      filter dateFrom(query, value, _conn) do
        query |> where([d], d.list_date >= ^value)
    end

    @options param: :dateTo, cast: :date 
      filter dateTo(query, value, _conn) do
        query |> where([d], d.list_date <= ^value)
      end

    @options param: :conid, cast: :integer
        filter conID(query, value, _conn) do
          query  |> where([d], d.consultant_id <= ^value)         
    end

  end



 def index(conn, params) do
    with {:ok, query, filter_values} <- apply_filters(User_take_list, conn),
         user_take_lists                       <- Repo.all(query) |>Decoratex.decorate,

     do: render(conn, index.json, user_take_lists: user_take_lists, meta: filter_values)
  end


  def show(conn, %{id => id}) do
    user_take_list = UTL.get_user_take_list!(id)
    render(conn, show.json, user_take_list: user_take_list)
  end

end

Je suis très nouveau pour Elixir et je ne peux pas chasser la nature de cette erreur. Si j'inspecter le struct je peux voir un champ user_age avec une valeur nulle, mais je ne sais pas si le problème est causé par ma propre fonction d'aide ou par la façon dont je me sers DecorateX.decorate.

Comme l'a demandé dans les commentaires, l'erreur avec stacktrace:

[info] GET /api/user_take_list
[debug] Processing with InformAPIWeb.User_take_listController.index/2
  Parameters: %{}
  Pipelines: [:api]
[debug] QUERY OK source=user_take_lists db=0.0ms decode=16.0ms
SELECT m0.id, m0.date_of_birth, m0.first_name, m0.last_name, m0.user_id, m0.needs_senior_review, m0.stable, m0.list_date, m0.consultant_id, m0.inserted_at, m0.updated_at FROM user_take_lists AS m0 []
[info] Sent 500 in 141ms
[error] #PID<0.390.0> running InformAPIWeb.Endpoint (cowboy_protocol) terminated
Server: localhost:4000 (http)
Request: GET /api/user_take_list
** (exit) an exception was raised:
    ** (FunctionClauseError) no function clause matching in Decoratex.decorate/1
        (decoratex) lib/decoratex.ex:145: Decoratex.decorate([%InformAPI.UTL.User_take_list{__meta__: #Ecto.Schema.Metadata<:loaded, user_take_lists>, consultant: #Ecto.Association.NotLoaded<association :consultant is not loaded>, consultant_id: 3, date_of_birth: ~D[1987-02-13], first_name: Hal, id: 1, inserted_at: ~N[2018-09-19 10:58:49.194000], last_name: Bradley, list_date: ~D[2018-09-13], needs_senior_review: true, user_age: nil, user_id: D00001, stable: true, updated_at: ~N[2018-09-19 10:58:49.194000]}, %InformAPI.UTL.User_take_list{__meta__: #Ecto.Schema.Metadata<:loaded, user_take_lists>, consultant: #Ecto.Association.NotLoaded<association :consultant is not loaded>, consultant_id: 3, date_of_birth: ~D[1987-02-13], first_name: Isobel, id: 2, inserted_at: ~N[2018-09-19 10:58:49.211000], last_name: Rogers, list_date: ~D[2018-09-13], needs_senior_review: false, user_age: nil, user_id: D00001, stable: true, updated_at: ~N[2018-09-19 10:58:49.211000]}, %InformAPI.UTL.User_take_list{__meta__: #Ecto.Schema.Metadata<:loaded, user_take_lists>, consultant: #Ecto.Association.NotLoaded<association :consultant is not loaded>, consultant_id: 2, date_of_birth: ~D[1987-02-13], first_name: Oliver, id: 3, inserted_at: ~N[2018-09-19 10:58:49.220000], last_name: Barton, list_date: ~D[2018-09-13], needs_senior_review: true, user_age: nil, user_id: D00001, stable: true, updated_at: ~N[2018-09-19 10:58:49.220000]}])
        (inform_api) lib/inform_api_web/controllers/user_take_list_controller.ex:37: InformAPIWeb.User_take_listController.index/2
        (inform_api) lib/inform_api_web/controllers/user_take_list_controller.ex:1: InformAPIWeb.User_take_listController.action/2
        (inform_api) lib/inform_api_web/controllers/user_take_list_controller.ex:1: InformAPIWeb.User_take_listController.phoenix_controller_pipeline/2
        (inform_api) lib/inform_api_web/endpoint.ex:1: InformAPIWeb.Endpoint.instrument/4
        (phoenix) lib/phoenix/router.ex:278: Phoenix.Router.__call__/1
        (inform_api) lib/inform_api_web/endpoint.ex:1: InformAPIWeb.Endpoint.plug_builder_call/2
        (inform_api) lib/plug/debugger.ex:122: InformAPIWeb.Endpoint.call (overridable 3)/2
        (inform_api) lib/inform_api_web/endpoint.ex:1: InformAPIWeb.Endpoint.call/2
        (plug) lib/plug/adapters/cowboy/handler.ex:16: Plug.Adapters.Cowboy.Handler.upgrade/4
        (cowboy) c:/Users/dbradley/Projects/inform-api/deps/cowboy/src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4
Créé 19/09/2018 à 13:21
source utilisateur
Dans d'autres langues...                            


1 réponses

voix
1

Selon la documentation de decoratex, Decoratex.decorate/1accepte un seul élément, pas une liste.

En changeant

Repo.all(query) |> Decoratex.decorate

à

Repo.all(query) |> Enum.map(&Decoratex.decorate/1)

devrait marcher.

Créé 19/09/2018 à 13:50
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more