2015-11-17 1 views
1

J'ai le modèle Ecto ci-dessous. Quand je rends, je veux que le JSON substitue le nom de propriété "layers" à "tilemap_layers".Poison.Encoder comment renommer les propriétés dans JSON rendu?

Il y a plusieurs types de 'couches' dans mon application, donc quand j'ai créé mon schéma de base de données, j'ai dû créer un schéma avec un nom unique. Cependant, ce JSON sera consommé par un client tiers où il doit être nommé "couches".

Quelle est la méthode recommandée pour ce faire?

Le modèle est ici:

defmodule MyProject.Tilemap do 
    use MyProject.Web, :model 

    @derive {Poison.Encoder, only: [ 
    :name, 
    :tile_width, 
    :tile_height, 
    :width, 
    :height, 
    :orientation, 
    :tilemap_layers, 
    :tilesets 
    ]} 

    schema "tilemaps" do 

    field :name, :string 
    field :tile_width, :integer 
    field :tile_height, :integer 
    field :width, :integer 
    field :height, :integer 
    field :orientation, :string 

    has_many :tilemap_layers, MyProject.TilemapLayer 
    has_many :tilesets, MyProject.Tileset 

    timestamps 
    end 

    @required_fields ~w(tile_width tile_height width height) 
    @optional_fields ~w() 

    @doc """ 
    Creates a changeset based on the `model` and `params`. 

    If no params are provided, an invalid changeset is returned 
    with no validation performed. 
    """ 
    def changeset(model, params \\ :empty) do 
    model 
    |> cast(params, @required_fields, @optional_fields) 
    end 
end 

Répondre

3

Poison ne fournit pas un moyen d'alias lors de l'utilisation @deriving

Vous pouvez:

préciser la mise en œuvre vous-même avec defimpl (prise de the docs) :

defimpl Poison.Encoder, for: Person do 
    def encode(%{name: name, age: age}, _options) do 
    Poison.Encoder.BitString.encode("#{name} (#{age})") 
    end 
end 

Renommer le champ dans le schéma:

has_many :layers, MyProject.TilemapLayer

ou utilisez un Phoenix Vue:

defmodule MyProject.TilemapView do 
    use MyProject.Web, :view 

    def render("index.json", %{tilemaps: timemaps}) do 
    render_many(tilemaps, __MODULE__, "tilemap.json") 
    end 

    def render("tilemap.json", %{tilemap: tilemap}) do 
    %{ 
     name: tilemap.name, 
     ... 
     layers: render_many(layers, MyProject.TilemapLayerView, "tilemap_layer.json") 
    } 
    end 
end 

Ensuite, créez un TilemapLayerView:

+0

Merci encore Gazler! J'essaie l'option foreign_key puisque c'est ce que je veux vraiment –

+0

Woot! Cela a fonctionné! J'aurais besoin de changer une petite faute de frappe. J'ai changé foreign_key:: tilemap_id –

+0

@JoshPetitt Vous n'avez probablement pas besoin de spécifier 'foreign_key'. Pourriez-vous l'essayer sans? – Gazler