无法转换为查询中的类型:id的值

时间:2018-10-11 15:13:21

标签: elixir phoenix-framework ecto

我正在尝试将我的评论添加到帖子中,以便用户访问/ posts /:id / comments时,他/她可以查看与该帖子相关的所有评论。

这是我的路由器

resources "/posts", PostController, except: [:new, :edit] do
   resources "/comments", CommentController, except: [:new, :edit]
end

然后是我的后控制器:

def index(conn, _params) do
    post = Posts.list_posts()
    render(conn, "index.json", posts: posts)
end

def create(conn, post_params) do
    with {:ok, %Post{} = post} <-Posts.create_post(post_params) do 
       #create_post is from post context
    conn
    |> put_status(:created)
    |> put_resp_header("location", post_path(conn, :show, post))
    |> render("show.json", post: post)
  end
end

def show(conn, %{"id" => id}) do
    post = Repo.get!(Post, id)
    comment_changeset = Comment.changeset(%Comment{})
    render(conn, "show.json", post: post, comment_changeset: 
    comment_changeset)
end

我的评论控制者:

def index(conn, _params) do
    comment= Comment.list_comment() #from comment context
    render(conn, "index.json", comments: comments)
end

def create(conn, comment_params) do
    post = Repo.get(Post, comment_params)
    comment_changeset = Ecto.build_assoc(post, :comment, 
    comment_params)
    Repo.insert(comment_changeset)

    conn
    |> put_status(:created)
    |> render("show.json")
end

def show(conn, %{"id" => id}) do
  comment = Comment.get_comment!(id) #from comment context
  render(conn, "show.json", comment: comment
end

当我尝试在post /:id / comments中添加新评论时,会引发此错误:

(Ecto.Query.CastError) deps/ecto/lib/ecto/repo/queryable.ex:348: value 
`%{"description" => "bitcoin", "post_id" => "2", "name" => "ethereum"}` 
in `where` cannot be cast to type :id in query:

from m in Myapp.Posts.Post,
 where: p.id == ^%{"description" => "bitcoin", "post_id" => "2", "name" 
=> "ethereum"},
  select: p

这是我的Myapp.Posts.Post:

schema "posts" do
    field :description, :string
    field :name, :string
    has_many :comments, Myapp.Comments.Comment
    field :body, :string

    timestamps()
  end

  @doc false
 def changeset(post, attrs) do
    post
    |> cast(attrs, [:name, :description, :body])
    |> validate_required([:name, :body ])
 end

还有我的Myapp.Comments.Comment

 schema "comments" do
    field :description, :string
    field :name, :string
    belongs_to :market, Myapp.Posts.Post

    timestamps()
 end

  @doc false
 def changeset(comment, attrs) do
    pair
    |> cast(attrs, [:name, :description])
    |> validate_required([:name, :description])
 end

从错误中,我认为ecto试图将整个请求参数作为p.id传递,但事实并非如此,请如何解决?我对此进行了很多研究,并尝试了一些更改,但遇到了不同的错误。

1 个答案:

答案 0 :(得分:0)

问题在这里:

Repo.get(Post, comment_params)

注释参数是控制器收到的内容,这是您在错误消息中看到的内容:

%{"description" => "bitcoin", "post_id" => "2", "name" => "ethereum"}

OTOH Repo.get/3希望将帖子ID作为第二个字段。这样的事情会起作用:

def create(conn, %{"post_id" => id} = comment_params) do
  post = Repo.get(Post, String.to_integer(id))