Could not render "review.json", please define a matching clause for render/2 or define a template at "web/templates/search"

I have my controller as bellow

defmodule Ceecare.SearchController do
   use Ceecare.Web, :controller
   alias Ceecare.{Repo, Review}

   def index(conn, _params) do
       reviews = Review
       |> Review.by_published(true)
       |> Review.order_by_date(:desc)
       |> Repo.all()
       |> Repo.preload([:category])

       conn
       |> render("index.json", reviews: reviews)
   end
end

and my search_view.ex as below

defmodule Ceecare.SearchView do
    use Ceecare.Web, :view

    def render("index.json", %{reviews: reviews}) do
        %{data: render_many(reviews, __MODULE__, "review.json")}
    end

    def render("show.json", %{review: review}) do
        %{data: render_one(review, __MODULE__, "review.json")}
    end

    def render("review.json", %{review: review}) do
        %{
            id: review.id,
            title: review.title
        }
    end
end

but i keep getting Could not render "review.json" for Ceecare.SearchView, please define a matching clause for render/2 or define a template at "web/templates/search". No templates were compiled for this module. Assigns:

I have deleted the build and recompiled and it’s the same.

I have google this and the solution i saw points to the same code i’ve written.

I’m using elixir 1.4.4 and phoenix 1.2.0

Thanks.

2 Likes

You are not passing reviews to the render_many/4 and render_one/4 functions. This is leading to a pattern match because you are explicitly looking for a :review key in the assigns which currently is not there.

1 Like

Thanks immensely for pointing this out to me.

I was thinking this line already did that:

%{data: render_many(reviews, __MODULE__, "review.json")}

If not please can you point me to a skeleton code achieving that.

Thanks.

If you look at the documentation for render_many/4, you will see the following

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

So what is actually happening here is because you are currently in the SearchView, the key it will be assigned is :search instead of :review. Just use the :as option to tell it what to use.

render_many(reviews, __MODULE__, "review.json", as: :review)

12 Likes

@Ankhers you are great!

Thanks immensely for pointing me to this. In fact i’ve read that line a couple of times but couldn’t reall figure that out.

Thanks immensely and God bless you real good in Jesus name, Amen.

I appreciate you and your time!

4 Likes

You should submit a PR to clarify that line then. :slight_smile: