我正在尝试创建一个小型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函数最优雅的实现是什么?