I used "mix phoenix.gen.json" to generate the code for rendering json resulting in view below:
defmodule Pghm.SightingsView do
use Pghm.Web, :view
def render("sighting.json", %{sighting: sighting}) do
%{what: sighting.what,
lat: sighting.lat,
long: sighting.long}
end
def render("index.json", %{sightings: sightings}) do
%{data: render_many(sightings, Pghm.SightingsView, "sighting.json")}
end
def render("show.json", %{sighting: sighting}) do
%{data: render_one(sighting, Pghm.SightingsView, "sighting.json")}
end
end
However when I attempt to access call it I receive: Could not render "sighting.json" for Pghm.SightingsView, please define a matching clause for render/2 or define a template at "web/templates/sightings". No templates were compiled for this module. Assigns:
Everywhere I've looked indicates that this should work, but I get no love.
I started with Phoenix recently too, but probably I know what's the problem.
def render("sighting.json", %{sighting: sighting}) do
%{what: sighting.what,
lat: sighting.lat,
long: sighting.long}
end
The definition of this function says, that it will work only if you call it this way:
render("sighting.json", %{sighting: some_data})
But this code:
%{data: render_many(sightings, Pghm.SightingsView, "sighting.json")}
Passes a sightings itself to render's second parameter, not the required %{sighting: sighting} thing. So Elixir couldn't find a render implementation that suits given parameters and raises the error.
Changing
def render("sighting.json", %{sighting: sighting}) do
to just
def render("sighting.json", sighting) do
should do the trick.
I've had exactly this problem today, and it was because I pluralised the view's name, like in Rails.
According to comments in the Phoenix source (1), the key is inferred from the view name.
A collection is any enumerable of structs. This function returns the rendered collection in a list:
render_many users, UserView, "show.html"
is roughly equivalent to:
Enum.map(users, fn user ->
render(UserView, "show.html", user: user)
end)
The underlying user is passed to the view and template as
:user
, which is inferred from the view name. The name of the key in assigns can be customized with the:as
option
(1) https://github.com/phoenixframework/phoenix/blob/8a6beef9e13f049a8458db25b71fb70afae7673a/lib/phoenix/view.ex#L267
So try this :
defmodule Pghm.SightingView do
use Pghm.Web, :view
def render("sighting.json", %{sighting: sighting}) do
%{what: sighting.what,
lat: sighting.lat,
long: sighting.long}
end
def render("index.json", %{sightings: sightings}) do
%{data: render_many(sightings, Pghm.SightingView, "sighting.json")}
end
def render("show.json", %{sighting: sighting}) do
%{data: render_one(sighting, Pghm.SightingView, "sighting.json")}
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With