使用更改集验证和处理复杂输入的优雅方法

时间:2016-07-17 03:28:04

标签: phoenix-framework ecto

我正在尝试创建一个小型Phoenix应用程序,并且无法找到处理从控制器到模型的用户输入的最佳方法。

我有2个模型和1个控制器:

defmodule MyApp.Post do
  use MyApp.Web, :model

  schema "posts" do
    field :title, :string
    field :text, :string
    field :comments_count, :integer
    has_many :comments, MyApp.Comment

    timestamps()
  end
end

defmodule MyApp.Comment do
  use MyApp.Web, :model

  schema "comments" do
    field :text, :string
    field :parent_path, :string # I want to store comments in a tree, using "Materialized Path" method
    belongs_to :post, MyApp.Post

    timestamps()
  end

  defmodule Ops do
    # I keep all operations that are related to comments in this module

    alias MyApp.{Repo, Comment}

    def create_by_user(params) do
      # params came straight from the controller. Expected fields are:
      # 1. text - text of the comment, required
      # 2. post_id - id of the post, required
      # 3. parent_id - id of the parent comment, optional

      # This function must:
      # 1. Validate presence of the text (this is simple)
      # 2. Check that post with given "post_id" exists
      # 3. If "parent_id" is given:
      # 3.1. Check that parent comment exists and belongs to the same post
      # 3.2. Based on fields of parent comment, calculate the "parent_path" value of the new comment
      # 4. If input is valid, insert a new comment to database and update post's "comments_count" field
    end
  end
end

defmodule MyApp.CommentController do
  use MyApp.Web, :controller

  alias MyApp.{Post, Comment}

  def create(conn, params) do
    case Comment.Ops.create_by_user(params) do
      {:ok, comment} -> conn |> put_status(200) |> json("not implemented yet")
      {:error, changeset} -> conn |> put_status(422) |> json("not implemented yet")
      # Also, in case of error, it would be nice to look into changeset.errors and if post wasn't found, return 404 
    end
  end
end

Comment.Ops.create_by_user函数最优雅的实现是什么?

0 个答案:

没有答案