1
votes

I'm utilizing the Plug.Upload struct in a form for a Phoenix app I'm working on to allow images to be uploaded and associated with a news article. For some reason when I upload an image and submit the form, flash notices and redirect/render does not work. The app instead reverts back to a blank new form even though the previous form was submitted successfully and data persisted to the db. I can manually go back to the index page and see that the article was created. When I do not upload an image, everything works as expected upon submission of the form.

Relevant form code:

<%= form_for @changeset, @action, [multipart: true], fn f -> %>

...

<div class="form-group">
  <label class="control-label">Upload Photo</label>
  <%= file_input f, :photo, class: "form-control" %>
  <%= error_tag f, :photo %>
</div>

Relevant controller code:

def create(conn, %{"article" => article_params}) do
  image = if article_params["photo"], do: article_params["photo"], else: nil

  changeset = if image do
                File.cp!(image.path, "./web/static/assets/images/articles/" <> image.filename)
                Article.changeset(%Article{}, article_params)
                |> Ecto.Changeset.change(img_url: "/images/articles/" <> image.filename)
              else
                Article.changeset(%Article{}, article_params)
              end

  case Repo.insert(changeset) do
    {:ok, article} ->
      conn
      |> put_flash(:info, "Article created successfully.")
      |> redirect(to: article_path(conn, :show, article))
    {:error, changeset} ->
      if image do
        File.rm("./web/static/assets/images/articles/" <> image.filename)
        File.rm("./priv/static/images/articles/"       <> image.filename)
      end
      render(conn, "new.html", changeset: changeset)
  end
end

Any insight would be greatly appreciated. If you need more info or me to add additional code, please let me know. Thanks!

1
And no errors are printed to the console? Are you sure Repo.insert results in {:ok, _}? Can you add some print statements and try to trace which lines of codes (e.g. which branches of if and case) were actually executed?Dogbert
I did an IO.inspect on Repo.insert(changeset) and got {:ok, _}. It's like once the Plug.Upload process terminates or resets it bypasses the case statements.jsonkenl
What if you add |> IO.inspect after the redirect call? (IO.inspect returns the argument passed so the code should work the same except also print the value.)Dogbert
resp_headers contains {"location", "/articles/22"}. Did you get redirected there? If not, you should debug this in Chrome DevTools -> Network tab and see what headers were actually received by the browser after submitting the form.Dogbert

1 Answers

1
votes

Found the solution, the problem is with live reload,this only happened with google chrome but you can change your live reload to not watch the dir in which you are uploading your images, you should change your config/dev.exs live_reload.

config :app, App.Endpoint,
live_reload: [
  patterns: [
    ~r{priv/static/js/.*js$},
    ~r{priv/static/css/.*css$},
    ~r{priv/static/css/images/.*(png|jpeg|jpg|gif|svg)$},
    ~r{priv/gettext/.*(po)$},
    ~r{web/views/.*(ex)$},
    ~r{web/templates/.*(eex)$}
  ]
]

And of course if you are uploading to priv/static folder you should not upload to css, js or images folder