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 %>