Elixir Phoenix中put_session更新数据页面切换后不持久化问题
问题原因及解决办法
核心问题1:首页每次访问都会重置session
你在首页设置的代码conn |> put_session(:open_articles, [])会每次访问首页时把open_articles强制重置为空数组,直接清空之前添加的记录。正确的做法是只在session中没有这个键时才初始化:
# 替换首页控制器里的初始化代码 conn = case get_session(conn, :open_articles) do nil -> conn |> put_session(:open_articles, []) _ -> conn end
或者更简洁的写法:
conn = conn |> put_session(:open_articles, get_session(conn, :open_articles) || [])
核心问题2:必须返回修改后的conn
在编辑页面的控制器动作中,修改session后,一定要用更新后的conn生成响应,否则Phoenix不会把session变更持久化到客户端。示例代码如下:
def edit(conn, %{"id" => id}) do article = Repo.get(Article, id) # 更新session updated_conn = conn |> put_session(:open_articles, [article.id | get_session(conn, :open_articles)]) # 必须返回更新后的conn用于渲染页面 render(updated_conn, "edit.html", article: article) end
如果只是修改了conn但没用来生成响应,session的变更不会被保存。
额外优化:避免重复添加同一文章
如果用户多次打开同一文章的编辑页,当前代码会重复添加ID到列表,可加去重逻辑:
current_open = get_session(conn, :open_articles) || [] new_open = if article.id not in current_open, do: [article.id | current_open], else: current_open updated_conn = conn |> put_session(:open_articles, new_open)
内容的提问来源于stack exchange,提问作者paulrusu
相关产品推荐
相关产品推荐

