Skip to content

Instantly share code, notes, and snippets.

@paulcsmith
Forked from jeregrine/comment_view.ex
Last active August 29, 2015 14:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save paulcsmith/057696e7c1c0accc7483 to your computer and use it in GitHub Desktop.
Save paulcsmith/057696e7c1c0accc7483 to your computer and use it in GitHub Desktop.
Rendering JSON with views
defmodule MyApp.CommentView do
use MyApp.Web, :view
@attributes ~W(id name inserted_at)
def render("index.json", %{data: comments}) do
for comment <- comments, do: render("show.json", %{data: comment})
end
def render("show.json", %{data: comment}) do
comment
|> Map.take(@attributes)
|> put_assoc(:user, comment.user)
end
end
defmodule MyApp.MyModelView do
use MyApp.Web, :view
@attributes ~W(id body title inserted_at)
def render("show.json", %{data: my_model})
my_model
|> Map.take(@attributes)
|> Map.update!(:title, &String.capitalize)
|> put_assoc(:user, my_model.user)
# Or you could do
# |> put_assoc(:user, my_model.user, :lite)
|> put_assoc(:comments, my_model.comments)
end
end
defmodule MyApp.UserView do
use MyApp.Web, :view
@attributes ~W(id name inserted_at)
def render("show.json", %{data: user})
render("show_lite.json", %{data: user})
|> Map.put(:image, ImageView.render("show.json", %{data: user.image})
end
def render("show_lite.json", %{data: user})
user
|> Map.take(@attributes)
end
end
defmodule MyApp.Web do
def view do
quote do
# Default code.
# You would probably extract these functions to a module.
def put_assoc(map, :user, user) do
Map.put(map, :user, UserView.render("show.json", %{data: user})
end
# Need to customize more?
def put_assoc(map, :user, user, :lite) do
Map.put(map, :user, UserView.render("show_lite.json", %{data: user})
end
def put_assoc(map, :comments, comments) do
Map.put(map, :comments, CommentView.render("index.json", %{data: comments})
end
end
end
end
@paulcsmith
Copy link
Author

I renamed show.json to index.json in the CommentView I think that makes more sense than show.json with a guard checking if it's a list.

@paulcsmith
Copy link
Author

I didn't test this so there might be some typos, but I added functions for adding associations more easily. Makes reading what will happen easier. Quicker to scan and see what it's doing. Also easier to use in other views. Still allows for customization and is a bit more imperative.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment