【发布时间】:2020-12-05 04:51:05
【问题描述】:
重新加载时,我似乎无法将任何消息持久化到数据库中。
它不显示任何错误消息。
为代码添加的链接。
room_channel.ex
defmodule Chat.RoomChannel do
use Phoenix.Channel
alias Chat.Presence
alias Chat.Repo
alias Chat.User
alias Chat.Message
def join("room", payload, socket) do
if authorized?(payload) do
send(self(), :after_join)
{:ok, socket}
else
{:error, %{reason: "unauthorized"}}
end
end
def handle_in("new_messages", payload, socket) do
spawn(fn -> save_message(payload) end)
user = Repo.get(User, socket.assigns.user_id)
broadcast! socket, "new_messages", %{user: user.name, message: payload["message"]}
{:noreply, socket}
end
def handle_info(:after_join, socket) do
Message.recent_messages()
|> Enum.each(fn msg -> push(socket, "new_messages", format_msg(msg)) end)
user = Repo.get(User, socket.assigns.user_id)
{:ok, _} = Presence.track(socket, user.name, %{
online_at: inspect(System.system_time(:seconds))
})
push socket, "presence_state", Presence.list(socket)
{:noreply, socket}
end
defp format_msg(msg) do
%{
name: msg.name,
message: msg.message
}
end
defp save_message(message) do
Message.changeset(%Message{}, message) |> Repo.insert
end
defp authorized?(_payload) do
true
end
end
message.ex
defmodule Chat.Message do
use Ecto.Schema
import Ecto.Changeset
schema "messages" do
field :name, :string
field :message, :string
timestamps()
end
@doc """
Builds a changeset based on the `struct` and `params`.
"""
def changeset(struct, params \\ %{}) do
struct
|> cast(params, [:name, :message])
|> validate_required([:name, :message])
end
def recent_messages(limit \\ 10) do
Chat.Repo.all(Chat.Message, limit: limit)
end
end
mix.exs
defp deps do
[{:phoenix, "~> 1.2.5"},
{:phoenix_pubsub, "~> 1.0"},
{:phoenix_ecto, "~> 3.0"},
{:postgrex, ">= 0.0.0"},
{:phoenix_html, "~> 2.6"},
{:phoenix_live_reload, "~> 1.0", only: :dev},
{:gettext, "~> 0.11"},
{:cowboy, "~> 1.0"},
{:coherence, "~> 0.3"}]
end
Elixir 1.11.2 (compiled with Erlang/OTP 23)
postgres (PostgreSQL) 13.0
我认为问题出在 room_channel.ex 中的 handle_in 函数上
spawn(fn -> save_message(payload) end)
任何指向正确方向的线索?
【问题讨论】:
-
如果您通过删除
spawn并只执行save_message(payload)来同步保存消息会发生什么?此外,您可能希望在save_message函数中处理无效的变更集——在尝试插入之前检查变更集是否有效。 -
仅使用
save_message(payload)没有任何变化。 -
考虑直接向您的问题发布代码,而不是通过外部链接
-
您不应该将
message["message"]传递给save_message函数中的变更集吗? -
@EvaldoBratti 如果我这样做会引发错误。
** (Ecto.CastError) expected params to be a map, got: "testing123"