shansiddiqui94

shansiddiqui94

I am following this tutorial. I have followed carefully correcting errors as I go. The app allows you to create a blog post and add comments if you so choose. I got the Blog post part up and running, I am having difficulty setting up the add comments part when I click show I get this error:

error] #PID<0.918.0> running BlogAppWeb.Endpoint (connection #PID<0.797.0>, stream id 13) terminated
Server: localhost:4000 (http)
Request: GET /posts/1
** (exit) an exception was raised:
    ** (Protocol.UndefinedError) protocol Enumerable not implemented for #Ecto.Association.NotLoaded<association :comments is not loaded> of type Ecto.Association.NotLoaded (a struct)
        (elixir 1.13.3) lib/enum.ex:1: Enumerable.impl_for!/1
        (elixir 1.13.3) lib/enum.ex:143: Enumerable.reduce/3
        (elixir 1.13.3) lib/enum.ex:4144: Enum.reduce/3
        (blog_app 0.1.0) lib/blog_app_web/templates/post/comments.html.eex:7: BlogAppWeb.PostView."comments.html"/1
        (blog_app 0.1.0) lib/blog_app_web/templates/post/show.html.heex:19: anonymous fn/2 in BlogAppWeb.PostView."show.html"/1
        (phoenix_live_view 0.17.7) lib/phoenix_live_view/engine.ex:124: Phoenix.HTML.Safe.Phoenix.LiveView.Rendered.to_iodata/1
        (phoenix_live_view 0.17.7) lib/phoenix_live_view/engine.ex:140: Phoenix.HTML.Safe.Phoenix.LiveView.Rendered.to_iodata/3
        (phoenix 1.6.6) lib/phoenix/controller.ex:772: Phoenix.Controller.render_and_send/4
        (blog_app 0.1.0) lib/blog_app_web/controllers/post_controller.ex:1: BlogAppWeb.PostController.action/2
        (blog_app 0.1.0) lib/blog_app_web/controllers/post_controller.ex:1: BlogAppWeb.PostController.phoenix_controller_pipeline/2
        (phoenix 1.6.6) lib/phoenix/router.ex:355: Phoenix.Router.__call__/2
        (blog_app 0.1.0) lib/blog_app_web/endpoint.ex:1: BlogAppWeb.Endpoint.plug_builder_call/2
        (blog_app 0.1.0) lib/plug/debugger.ex:136: BlogAppWeb.Endpoint."call (overridable 3)"/2
        (blog_app 0.1.0) lib/blog_app_web/endpoint.ex:1: BlogAppWeb.Endpoint.call/2
        (phoenix 1.6.6) lib/phoenix/endpoint/cowboy2_handler.ex:54: Phoenix.Endpoint.Cowboy2Handler.init/4
        (cowboy 2.9.0) /Users/shansiddiqui/Desktop/blog_app/deps/cowboy/src/cowboy_handler.erl:37: :cowboy_handler.execute/2
        (cowboy 2.9.0) /Users/shansiddiqui/Desktop/blog_app/deps/cowboy/src/cowboy_stream_h.erl:306: :cowboy_stream_h.execute/3
        (cowboy 2.9.0) /Users/shansiddiqui/Desktop/blog_app/deps/cowboy/src/cowboy_stream_h.erl:295: :cowboy_stream_h.request_process/3
        (stdlib 3.17) proc_lib.erl:226: :proc_lib.init_p_do_apply/3

and this is what comes on my webpage

My current Github has the updated app, can someone help me figure out what I am doing wrong?

Showing Posts 1 to 7

gregvaughn

gregvaughn

You need to preload the comments association of the blog before you try to render it. Ecto does not try to read your mind or have mutable state for lazy loading as other db frameworks do.

shansiddiqui94

shansiddiqui94 OP

I am sorry I am a complete beginner here, Would kindly guide me. How could I reload the comments first? the whole page loads at the same time.

gpopides

gpopides

<%= for comment <- @comments do %> this part tries to iterate over comments, but the comments don’t exist because as top comment mentions you haven’t loaded them.

in order to access a related model you need to preload it

shansiddiqui94

shansiddiqui94 OP

In reference to the tutorial, the guide does not do this? Is this because the tutorial is outdated

gregvaughn

gregvaughn

I don’t typically go read a beginner tutorial someone else is following, however, in this case I searched the page for “preload” and found under section 3 where comments are added, this is added to the posts_controller.ex

def add_comment(conn, %{"comment" => comment_params, "post_id" => post_id}) do
	post =
		post_id
		|> Posts.get_post!()
		|> Repo.preload([:comments])

That last line is preloading comments. And a couple of paragraphs later the blog states

We need to preload comments from the Repo …

shansiddiqui94

shansiddiqui94 OP

Here is my update :
This is my changeset Func:

 def changeset(comment, attrs) do
    comment
    |> cast(attrs, [:name, :content, :post_id])
    |> validate_required([:name, :content, :post_id])
  end
end

When I try to create a new Post I get an error that says changeset Function NOT found clearly its right there!!

Error

[info] Sent 302 in 83ms
[info] GET /posts/3
[debug] Processing with BlogAppWeb.PostController.show/2
  Parameters: %{"id" => "3"}
  Pipelines: [:browser]
[debug] QUERY OK source="posts" db=4.4ms queue=0.3ms idle=1176.0ms
SELECT p0."id", p0."body", p0."title", p0."inserted_at", p0."updated_at" FROM "posts" AS p0 WHERE (p0."id" = $1) [3]
[info] Sent 500 in 95ms
[error] #PID<0.622.0> running BlogAppWeb.Endpoint (connection #PID<0.572.0>, stream id 14) terminated
Server: localhost:4000 (http)
Request: GET /posts/3
** (exit) an exception was raised:
    ** (KeyError) key :changeset not found in: %{conn: %Plug.Conn{adapter: {Plug.Cowboy.Conn, :...}, assigns: %{layout: {BlogAppWeb.LayoutView, "app.html"}, post: %BlogApp.Posts.Post{__meta__: #Ecto.Schema.Metadata<:loaded, "posts">, body: "Test # 3", comments: #Ecto.Association.NotLoaded<association :comments is not loaded>, id: 3, inserted_at: ~N[2022-03-18 17:50:15], title: "Hello", updated_at: ~N[2022-03-18 17:50:15]}}, body_params: %{}, cookies: %{"_blog_app_key" => "SFMyNTY.g3QAAAACbQAAAAtfY3NyZl90b2tlbm0AAAAYSjBybkJSX2U0ZHVyalNoLVkzeHhCdlRtbQAAAA1waG9lbml4X2ZsYXNodAAAAAFtAAAABGluZm9tAAAAGlBvc3QgY3JlYXRlZCBzdWNjZXNzZnVsbHku.-BzmBjG1xDvxVI_skwFYETUR8AELIPVemAJIDpKWZFs", "_live_view_todos_key" => "SFMyNTY.g3QAAAABbQAAAAtfY3NyZl90b2tlbm0AAAAYWWJ1XzE5MnJSSkV6OVl3eVl0cUpvM2pN.NJYDbH-n7JlaQFMHL2_x-T2zhhvyYD6XBmo8GequxP8"}, halted: false, host: "localhost", method: "GET", owner: #PID<0.622.0>, params: %{"id" => "3"}, path_info: ["posts", "3"], path_params: %{"id" => "3"}, port: 4000, private: %{BlogAppWeb.Router => {[], %{Plug.Swoosh.MailboxPreview => ["mailbox"]}}, :before_send => [#Function<0.16477574/1 in Plug.CSRFProtection.call/2>, #Function<2.17183421/1 in Phoenix.Controller.fetch_flash/2>, #Function<0.77458138/1 in Plug.Session.before_send/2>, #Function<0.23023616/1 in Plug.Telemetry.call/2>, #Function<1.46227650/1 in Phoenix.LiveReloader.before_send_inject_reloader/3>], :phoenix_action => :show, :phoenix_controller => BlogAppWeb.PostController, :phoenix_endpoint => BlogAppWeb.Endpoint, :phoenix_flash => %{"info" => "Post created successfully."}, :phoenix_format => "html", :phoenix_layout => {BlogAppWeb.LayoutView, :app}, :phoenix_request_logger => {"request_logger", "request_logger"}, :phoenix_root_layout => {BlogAppWeb.LayoutView, :root}, :phoenix_router => BlogAppWeb.Router, :phoenix_template => "show.html", :phoenix_view => BlogAppWeb.PostView, :plug_session => %{"_csrf_token" => "J0rnBR_e4durjSh-Y3xxBvTm", "phoenix_flash" => %{"info" => "Post created successfully."}}, :plug_session_fetch => :done}, query_params: %{}, query_string: "", remote_ip: {127, 0, 0, 1}, req_cookies: %{"_blog_app_key" => "SFMyNTY.g3QAAAACbQAAAAtfY3NyZl90b2tlbm0AAAAYSjBybkJSX2U0ZHVyalNoLVkzeHhCdlRtbQAAAA1waG9lbml4X2ZsYXNodAAAAAFtAAAABGluZm9tAAAAGlBvc3QgY3JlYXRlZCBzdWNjZXNzZnVsbHku.-BzmBjG1xDvxVI_skwFYETUR8AELIPVemAJIDpKWZFs", "_live_view_todos_key" => "SFMyNTY.g3QAAAABbQAAAAtfY3NyZl90b2tlbm0AAAAYWWJ1XzE5MnJSSkV6OVl3eVl0cUpvM2pN.NJYDbH-n7JlaQFMHL2_x-T2zhhvyYD6XBmo8GequxP8"}, req_headers: [{"accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"}, {"accept-encoding", "gzip, deflate, br"}, {"accept-language", "en-US,en;q=0.9"}, {"cache-control", "max-age=0"}, {"connection", "keep-alive"}, {"cookie", "_live_view_todos_key=SFMyNTY.g3QAAAABbQAAAAtfY3NyZl90b2tlbm0AAAAYWWJ1XzE5MnJSSkV6OVl3eVl0cUpvM2pN.NJYDbH-n7JlaQFMHL2_x-T2zhhvyYD6XBmo8GequxP8; _blog_app_key=SFMyNTY.g3QAAAACbQAAAAtfY3NyZl90b2tlbm0AAAAYSjBybkJSX2U0ZHVyalNoLVkzeHhCdlRtbQAAAA1waG9lbml4X2ZsYXNodAAAAAFtAAAABGluZm9tAAAAGlBvc3QgY3JlYXRlZCBzdWNjZXNzZnVsbHku.-BzmBjG1xDvxVI_skwFYETUR8AELIPVemAJIDpKWZFs"}, {"host", "localhost:4000"}, {"referer", "http://localhost:4000/posts/new"}, {"sec-ch-ua", "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"98\", \"Google Chrome\";v=\"98\""}, {"sec-ch-ua-mobile", "?0"}, {"sec-ch-ua-platform", "\"macOS\""}, {"sec-fetch-dest", "document"}, {"sec-fetch-mode", "navigate"}, {"sec-fetch-site", "same-origin"}, {"sec-fetch-user", "?1"}, {"upgrade-insecure-requests", "1"}, {"user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"}], request_path: "/posts/3", resp_body: nil, resp_cookies: %{}, resp_headers: [{"cache-control", "max-age=0, private, must-revalidate"}, {"x-request-id", "Ft2K8xb5O7AJv6MAAANC"}, {"x-frame-options", "SAMEORIGIN"}, {"x-xss-protection", "1; mode=block"}, {"x-content-type-options", "nosniff"}, {"x-download-options", "noopen"}, {"x-permitted-cross-domain-policies", "none"}, {"cross-origin-window-policy", "deny"}], scheme: :http, script_name: [], secret_key_base: :..., state: :unset, status: nil}, post: %BlogApp.Posts.Post{__meta__: #Ecto.Schema.Metadata<:loaded, "posts">, body: "Test # 3", comments: #Ecto.Association.NotLoaded<association :comments is not loaded>, id: 3, inserted_at: ~N[2022-03-18 17:50:15], title: "Hello", updated_at: ~N[2022-03-18 17:50:15]}}
        (blog_app 0.1.0) lib/blog_app_web/templates/post/show.html.heex:19: anonymous fn/2 in BlogAppWeb.PostView."show.html"/1
        (phoenix_live_view 0.17.7) lib/phoenix_live_view/engine.ex:124: Phoenix.HTML.Safe.Phoenix.LiveView.Rendered.to_iodata/1
        (phoenix_live_view 0.17.7) lib/phoenix_live_view/engine.ex:140: Phoenix.HTML.Safe.Phoenix.LiveView.Rendered.to_iodata/3
        (phoenix 1.6.6) lib/phoenix/controller.ex:772: Phoenix.Controller.render_and_send/4
        (blog_app 0.1.0) lib/blog_app_web/controllers/post_controller.ex:1: BlogAppWeb.PostController.action/2
        (blog_app 0.1.0) lib/blog_app_web/controllers/post_controller.ex:1: BlogAppWeb.PostController.phoenix_controller_pipeline/2
        (phoenix 1.6.6) lib/phoenix/router.ex:355: Phoenix.Router.__call__/2
        (blog_app 0.1.0) lib/blog_app_web/endpoint.ex:1: BlogAppWeb.Endpoint.plug_builder_call/2
        (blog_app 0.1.0) lib/plug/debugger.ex:136: BlogAppWeb.Endpoint."call (overridable 3)"/2
        (blog_app 0.1.0) lib/blog_app_web/endpoint.ex:1: BlogAppWeb.Endpoint.call/2
        (phoenix 1.6.6) lib/phoenix/endpoint/cowboy2_handler.ex:54: Phoenix.Endpoint.Cowboy2Handler.init/4
        (cowboy 2.9.0) /Users/shansiddiqui/Desktop/blog_app/deps/cowboy/src/cowboy_handler.erl:37: :cowboy_handler.execute/2
        (cowboy 2.9.0) /Users/shansiddiqui/Desktop/blog_app/deps/cowboy/src/cowboy_stream_h.erl:306: :cowboy_stream_h.execute/3
        (cowboy 2.9.0) /Users/shansiddiqui/Desktop/blog_app/deps/cowboy/src/cowboy_stream_h.erl:295: :cowboy_stream_h.request_process/3
        (stdlib 3.17) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
al2o3cr

al2o3cr

General tip: you’ll get better help if you show the corresponding code along with the error message. What is on line 19 of lib/blog_app_web/templates/post/show.html.heex?

Based on the code up on Github, I’m guessing it’s the same code that’s on line 24 here:

The error is telling you that the view is looking for an assign named changeset but not finding it.

In the corresponding controller, changeset is passed to many other calls to render but not for the show action:

— All posts loaded —

Where Next? Top

Trending in Questions Top

Blokh
Hey guys, I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly Do you guys have any suggestions what is the best prac...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
Onor.io
I have what I’ve heard referred to as a “lookup table” in my database. This is a way of assigning codes to common values. One common lo...
New
Trolleger
What approach to take when sending live updates to “random” users Hi! I have a question, I have a little chat app, and when I create a DM...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
matt-savvy
Anyone here using Honeybadger? My Honeybadger account is being overwhelmed with noise from some bots. Seeing a lot of Bandit.HTTPError...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews