【问题标题】:assign @categories not available in eex template分配 @categories 在 eex 模板中不可用
【发布时间】:2020-09-22 07:19:27
【问题描述】:

我有两个模型,产品和类别。我能够添加/编辑具有所选类别的产品,但现在在我设置 Arc 后,我遇到错误:当我尝试添加或编辑产品时,分配 @categories 在 eex 模板中不可用。有谁知道我做错了什么或者我的代码中缺少什么?我正在使用 Phoenix 1.4。

我的架构:

  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

在产品控制器中新建/编辑:

  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

我的产品形式:

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

【问题讨论】:

    标签: elixir phoenix-framework


    【解决方案1】:

    我猜当您执行 createupdate 失败时会弹出错误?

    解决方法:当你渲染有错误的表单时,不要忘记获取并分配categories

      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} ->
            categories = Repo.all(Category) |> Enum.map(&{&1.name, &1.id}) # <- ADD THIS
            render(conn, "new.html", changeset: changeset, categories: categories)
        end
      end
    

    update 函数也是如此。

    【讨论】:

    • 感谢您的帮助。我认为它有效,因为现在我可以添加/编辑产品,但只能没有图片。当我尝试添加/编辑带有图像的产品时,我在选择文件按钮下看到“无效”。在控制台中,我收到此消息:[error] {:error, ["Invalid Parameter - /plug-1591\r\n", "Invalid Parameter - /plug-1591\r\n"]} [debug] QUERY OK source="categories" db=0.0ms idle=532.0ms SELECT c0."id", c0."name", c0."subcategory", c0."inserted_at", c0."updated_at" FROM "categories" AS c0 [] 我猜是我的上传者的问题,但我完全不明白这条消息。
    • 您可以编写一个控制器插件,根据路由加载类别。您在插件中所要做的就是获取类别并放入分配映射,然后您编写一个插件:plug plug_name when action in [:new, :create]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-20
    • 2020-11-09
    • 2020-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-25
    相关资源
    最近更新 更多