2017-09-23 3 views
1

J'ai ce modèle et il fonctionne très bien# Ecto.Association.NotLoaded question

<h2>Listing videos</h2> 

<table class="table"> 
    <thead> 
    <tr> 
     <th>User</th> 
     <th>Url</th> 
     <th>Title</th> 
     <th>Description</th> 
     <th>Category</th> 
     <th></th> 
    </tr> 
    </thead> 
    <tbody> 
<%= for video <- @videos do %> 
    <tr> 
     <td><%= video.user_id %></td> 
     <td><%= video.url %></td> 
     <td><%= video.title %></td> 
     <td><%= video.description %></td> 
     <td><%= if category = video.category, do: category.name %></td> 

     <td class="text-right"> 
     <%= link "Show", to: video_path(@conn, :show, video), class: "btn btn-default btn-xs" %> 
     <%= link "Edit", to: video_path(@conn, :edit, video), class: "btn btn-default btn-xs" %> 
     <%= link "Delete", to: video_path(@conn, :delete, video), method: :delete, data: [confirm: "Are you sure?"], class: "btn btn-danger btn-xs" %> 
     </td> 
    </tr> 
<% end %> 
    </tbody> 
</table> 

<%= link "New video", to: video_path(@conn, :new) %> 

Et quand je l'ai écrit ce test il a commencé à se plaindre de catégories ne sont pas préchargés:

defmodule Rumbl.VideoViewTest do 
    use Rumbl.ConnCase, async: true 
    import Phoenix.View 

    test "renders index.html", %{conn: conn} do 
    videos = [%Rumbl.Video{id: "1", title: "dogs"}, 
       %Rumbl.Video{id: "2", title: "cats"}] 
    content = render_to_string(Rumbl.VideoView, "index.html", 
           conn: conn, videos: videos) 

    assert String.contains?(content, "Listing videos") 
    for video <- videos do 
     assert String.contains?(content, video.title) 
    end 
    end 

    test "renders new.html", %{conn: conn} do 
    changeset = Rumbl.Video.changeset(%Rumbl.Video{}) 
    categories = [{"cats", 123}] 
    content = render_to_string(Rumbl.VideoView, "new.html", 
     conn: conn, changeset: changeset, categories: categories) 
    assert String.contains?(content, "New video") 
    end 
end 

Erreur:

... 

    1) test renders index.html (Rumbl.VideoViewTest) 
    test/views/video_view_test.exs:5 
    ** (KeyError) key :name not found in: #Ecto.Association.NotLoaded<association :category is not loaded> 
    code: content = render_to_string(Rumbl.VideoView, "index.html", 
    stacktrace: 
     (rumbl) web/templates/video/index.html.eex:21: anonymous fn/3 in Rumbl.VideoView."index.html"/1 
     (elixir) lib/enum.ex:1811: Enum."-reduce/3-lists^foldl/2-0-"/3 
     (rumbl) web/templates/video/index.html.eex:15: Rumbl.VideoView."index.html"/1 
     (phoenix) lib/phoenix/view.ex:335: Phoenix.View.render_to_iodata/3 
     (phoenix) lib/phoenix/view.ex:342: Phoenix.View.render_to_string/3 
     test/views/video_view_test.exs:8: (test) 

Pourquoi se plaint-il? Où dois-je précharger les catégories? Je ne comprends pas cette erreur, si doesnt vidéo ont une catégorie, il ne devrait pas tomber en panne

Mise à jour avec le code de l'index des contrôleur

def index(conn, _params, user) do 
    videos = Repo.all(user_videos(user)) |> Repo.preload(:category) 
    render(conn, "index.html", videos: videos) 
    end 

Répondre

1

Oui, vous devez précharger catégorie dans le contrôleur.

Vous ne savez pas si la vidéo a une catégorie avant de la précharger (pas en demandant if video.category). C'est parce que video.category sans préchargement renvoie #Ecto.Association.NotLoaded<association :category is not loaded>, pas nil que vous avez prévu.

Pour une seule catégorie, vous pouvez demander if video.category_id, en supposant que la catégorie vidéo belongs_to. Il vous donnera nil si la vidéo n'a pas de catégorie.

+0

mm alors quelque chose comme ça pourrait fonctionner? <% = si video.category_id && category = video.category, faites: category.name%> même si j'ai des problèmes de syntaxe – lapinkoira

+0

Il pourrait, mais ce ne sera pas si la vidéo a une catégorie et il n'est pas préchargé. –

+0

mm J'ai remarqué que je suis déjà en train de précharger les catégories dans le controller videos = Repo.all (user_videos (user)) |> Repo.preload (: category) donc je ne devrais pas avoir l'erreur? – lapinkoira