Kapeusz
Image upload using Arc and nested form
Hi,
I have two models, Product and Category. After help I got from here I could add/edit a product with the chosen category, but now after I set up Arc I face same error again: assign @categories not available in eex template, when I try to add or edit a product. Anyone has an idea what I could have done wrong?
My schemas:
schema "products" do
field :avdate, :date
field :description, :string
field :name, :string
field :price, :float
field :prodimg, ShopifyWeb.DisplayImage.Type
field :quantity, :integer
field :subcategory, :integer
belongs_to :category, Shopify.Departments.Category
has_many :comments, Shopify.Reviews.Comment
timestamps()
end
@doc false
def changeset(product, attrs) do
product
|> cast(attrs, [:name, :quantity, :price, :subcategory, :description, :avdate, :category_id])
|> cast_attachments(attrs, [:prodimg])
|> validate_required([:name, :quantity, :price, :subcategory, :description, :avdate, :category_id])
end
---
schema "categories" do
field :name, :string
field :subcategory, :string
has_many :products, Shopify.Inventory.Product
timestamps()
end
@doc false
def changeset(category, attrs) do
category
|> cast(attrs, [:name, :subcategory])
|> validate_required([:name, :subcategory])
end
New/Edit in product controller:
def new(conn, _params) do
changeset = Inventory.change_product(%Product{})
categories = Repo.all(Category) |> Enum.map(&{&1.name, &1.id})
render(conn, "new.html", changeset: changeset, categories: categories)
end
def create(conn, %{"product" => product_params}) do
case Inventory.create_product(product_params) do
{:ok, product} ->
conn
|> put_flash(:info, "Product created successfully.")
|> redirect(to: Routes.product_path(conn, :show, product))
{:error, %Ecto.Changeset{} = changeset} ->
render(conn, "new.html", changeset: changeset)
end
end
def show(conn, %{"id" => id}) do
product = Inventory.get_product!(id)
comment_changeset = Reviews.change_comment(%Comment{})
render(conn, "show.html", product: product, comment_changeset: comment_changeset)
end
def edit(conn, %{"id" => id}) do
product = Inventory.get_product!(id)
changeset = Inventory.change_product(product)
categories = Repo.all(Category) |> Enum.map(&{&1.name, &1.id})
render(conn, "edit.html", product: product, changeset: changeset, categories: categories)
end
def update(conn, %{"id" => id, "product" => product_params}) do
product = Inventory.get_product!(id)
case Inventory.update_product(product, product_params) do
{:ok, product} ->
conn
|> put_flash(:info, "Product updated successfully.")
|> redirect(to: Routes.product_path(conn, :show, product))
{:error, %Ecto.Changeset{} = changeset} ->
render(conn, "edit.html", product: product, changeset: changeset)
end
end
My image uploader:
@acl :public_read
@versions [:primary, :thumbnail]
def transform(:primary, {_file, _product}) do
{:convert, "-resize 50%"}
end
def transform(:thumbnail, {_file, _product}) do
{:convert, "-resize 25%"}
end
def validate({file, _product}) do
file_extension = file.file_name
|> Path.extname()
|> String.downcase()
Enum.member?([".png"], file_extension)
end
def s3_object_headers(:primary, {file, _product}) do
%{content_type: MIME.from_path(file.file_name)}
end
def default_url(:primary, _product) do
"http://placehold.it/350x200"
end
def default_url(:thumbnail, _product) do
"http://placehold.it/175x100"
end
end
Display image in product_view.ex
def display_image(product, version) do
{product.prodimg, product}
|> DisplayImage.url(version)
|> img_tag()
end
end
And my product form
<%= form_for @changeset, @action, [multipart: true], fn f -> %>
<%= if @changeset.action do %>
<div class="alert alert-danger">
<p>Oops, something went wrong! Please check the errors below.</p>
</div>
<% end %>
<%= label f, :name %>
<%= text_input f, :name %>
<%= error_tag f, :name %>
<%= label f, :quantity %>
<%= number_input f, :quantity %>
<%= error_tag f, :quantity %>
<%= label f, :price %>
<%= number_input f, :price %>
<%= error_tag f, :price %>
<div class="form-group">
<%= select f, :category_id, @categories %>
<p class="help is-danger"><%= error_tag f, :category %></p>
</div>
<%= label f, :subcategory %>
<%= number_input f, :subcategory %>
<%= error_tag f, :subcategory %>
<%= label f, :description %>
<%= text_input f, :description %>
<%= error_tag f, :description %>
<%= label f, :avdate %>
<%= date_select f, :avdate %>
<%= error_tag f, :avdate %>
<div class="form-group">
<%= label f, :prodimg, class: "control-label" %>
<%= file_input f, :prodimg, class: "form-control" %>
<%= error_tag f, :prodimg %>
</div>
<div>
<%= submit "Save" %>
</div>
<% end %>
Marked As Solved
kokolegorille
Whenever You fail to create, or update, You rerender new.html, or update.html, but You don’t pass categories. So the template is not happy…
Like here… no categories are passed to the template. That’s why You have this error.
Last Post!
Kapeusz
Thanks for the help! I changed that. However, now i cannot add/edit a product because of an error “Is invalid” when I try to upload an image, in console:
[error] {:error, ["Invalid Parameter - /plug-1591\r\n", "Invalid Parameter - /plug-1591\r\n"]}
I totally don’t understand this error. I am trying to upload .png files just as stated in my uploader. When I add/edit a product without uploading any image everything works fine. Thanks in advance!
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex










