【问题标题】:Using a variable Struct使用变量结构
【发布时间】:2016-04-26 22:00:52
【问题描述】:

我正在尝试编写 DRY Elixir,而 Dave Thomas 的书仍在发布中!

您可以在下面看到为 Card 自动生成的 Phoenix 控制器的一部分。在实践中,我有多种产品的行为与Card 完全相同,所以我想概括一下。下面是我的一项努力,但它无法编译,错误为 **{}**。

我很确定自己犯了一个根本性错误,因为我是这门语言的新手(但不是函数式编程)。

  alias Api.Card

  map = %{"cards" => Card, "books" => Book}

  def create(conn, %{"product" => product}) do

    # changeset = Card.changeset(%Card{}, card_params)
    changeset = map[product].changeset(%map[product]**{}**, card_params)

    case Repo.insert(changeset) do
      {:ok, product} ->
        conn
        |> put_status(:created)
        |> put_resp_header("location", card_path(conn, :show, card))
        # |> render("show.json", card: card)
        |> render("new_key.json", id: product.id)

如果你能帮我解决这个问题,请注意我还需要将card_path 转换为变量,但我认为这将与estimate_path product 类似。

我也试过了,但也没有成功

  (Struct, path) =
    case product do
        "cards" -> (Card, card_path)
        _ -> (Card, card_path)
    end

【问题讨论】:

    标签: elixir


    【解决方案1】:

    如果你想创建一个空结构体(带有默认值),你可以在模块上调用自动生成的__struct__/0函数。

    改变

    changeset = map[product].changeset(%map[product]**{}**, card_params)
    

    changeset = map[product].changeset(map[product].__struct__, card_params)
    

    要将card_path 函数存储在变量中,至少有两个选项:

    1. 使用path = &card_path/3 存储对函数的引用,然后将其调用为path.(conn, :show, card)

    2. 将其存储为原子,如 path = :card_path 并使用 apply/3 调用它:apply(YourApp.Router.Helpers, path, [conn, :show, card])

    【讨论】:

    • 谢谢。第一点起作用了,我相信你对后者也是正确的。但为此,我使用的是 Phoenix 并且有 resources "/estimates/:product", EstimateController, except: [:new, :edit],所以我想知道是否也有办法使用 estimate_path
    • 这是惯用语吗?我问现在我看到我只能使用map,如果它在create 内,而我也需要它用于其他功能
    • 您应该使用模块属性来存储地图。在模块中使用@map %{...}定义它,然后在函数中使用@map访问它。
    • 第一个问题,您可以创建一个类似@map %{"cards" => %{module: Card, path: :card_path}, ...} 的地图,然后将:module 中的值用于__struct__,并将:pathapply 一起使用。
    猜你喜欢
    • 2018-09-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-14
    • 2021-04-07
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多