【问题标题】:Clean up Elixir/Phoenix map replacement code清理 Elixir/Phoenix 地图替换代码
【发布时间】:2016-06-03 23:46:47
【问题描述】:

您对我如何使这个更清洁有什么建议吗?

视频参数来自表单提交,因此映射为 %{"url" => "https://youtube.com/......", "title" => "Carneval in Rio de Janeiro", ... }

defp make_url_ready_for_embedding(video_params) do
  cond do
    String.contains? video_params["url"], "/watch?v=" ->
      video_params |> Map.put("url", String.replace(video_params["url"], "/watch?v=", "/embed/"))
    String.contains? video_params["url"], "https://vimeo.com" ->
      video_params |> Map.put("url", Regex.replace(~r/([^1-9]+)/, video_params["url"], "https://player.vimeo.com/video/"))
    true ->
      video_params
  end
end

如果有用的话,这是我的create 方法:

def create(conn, %{"video" => video_params}, user) do
    changeset = 
      user
      |> build_assoc(:videos)
      |> Video.changeset(video_params |> make_url_ready_for_embedding)

    case Repo.insert(changeset) do
      {:ok, _video} ->
        conn
        |> put_flash(:info, "Video created successfully.")
        |> redirect(to: video_path(conn, :index))
      {:error, changeset} ->
        render(conn, "new.html", changeset: changeset)
    end
  end

【问题讨论】:

    标签: elixir phoenix-framework


    【解决方案1】:

    逻辑是有道理的,但是行很长。

    我可能会选择类似的东西:

    defp make_url_ready_for_embedding(%{"url" => url} = video_params) do
      url = cond do
        String.contains?(url, "/watch?v=") ->
          String.replace(url, "/watch?v=", "/embed/")
        String.contains?(url "https://vimeo.com") ->
          Regex.replace(~r/([^1-9]+)/, url, "https://player.vimeo.com/video/")
        true ->
          url
      end
      %{video_params | "url" => url)
    end
    

    这样比较好,但是意图还是不是很清楚。我可能会考虑使用函数来帮助解决这个问题:

    defp make_url_ready_for_embedding(%{"url" => url} = video_params) do
      type = cond do
        youtube_video?(url) -> :youtube
        vimeo_video?(url)   -> :vimeo
        true                -> :unknown
      end
      %{video_params | "url" => transform_url(url, type)}
    end
    
    defp youtube_video?(url) do
      String.contains?(url, "/watch?v=")
    end
    
    defp vimeo_video?(url) do
      String.contains?(url, "https://vimeo.com")
    end
    
    defp transform_url(url, :unknown) do: url
    defp transform_url(url, :youtube) do
      String.replace(url, "/watch?v=", "/embed/")
    end
    defp transform_url(url, :vimeo) do
      Regex.replace(~r/([^1-9]+)/, url, "https://player.vimeo.com/video/")
    end
    

    这样做的好处是您可以测试您的transform_url 函数(将其设为公开且@doc 为假)以确保针对每种类型正确转换网址。

    【讨论】:

    • 我觉得挺好的。我已将函数移至单独的 video_transformers.ex 文件,现在正在导入它
    • defp youtube_video?/1 函数中有一个错字:String.contains?(url "https://vimeo.com") 应该有一个逗号,使它成为:String.contains?(url, "https://vimeo.com")
    猜你喜欢
    • 2018-02-03
    • 1970-01-01
    • 2016-10-22
    • 1970-01-01
    • 1970-01-01
    • 2018-08-24
    • 2018-05-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多