我的路由器中有一个users
资源,其中有一个供朋友使用的额外端点,如下所示:
resources "/users", UserController, except: [:create, :delete] do
get "/friends", UserController, :friends
end
这可行,但我朋友的路线是/api/users/:user_id/friends
。我如何将参数重命名为,id
以便我的路线变为/api/users/:id/friends
?
我的路由器中有一个users
资源,其中有一个供朋友使用的额外端点,如下所示:
resources "/users", UserController, except: [:create, :delete] do
get "/friends", UserController, :friends
end
这可行,但我朋友的路线是/api/users/:user_id/friends
。我如何将参数重命名为,id
以便我的路线变为/api/users/:id/friends
?
我最近更新了操作系统,现在运行服务器时遇到此错误。以前,一切正常。以下是错误消息:
(Mix) Could not start application main: Main.Application.start(:normal, []) returned an error: shutdown: failed to start child: Oban (EXIT) shutdown: failed to start child: {:via, Registry, {Oban.Registry, {Oban, Oban.Nursery}}} (EXIT) shutdown: failed to start child: {Oban.Registry, {Oban, Foreman}} (EXIT) an exception was raised: ** (ArgumentError) expected :strategy option to be given (elixir 1.12.2) lib/dynamic_supervisor.ex:516: DynamicSupervisor.init/1
这是我的文件中的配置application.ex
:
{Oban, Application.fetch_env!(:main, Oban)}
这是我在config.exs
文件中的配置:
config :main, Oban, repo: Data.Repo, queues: [ events: 10, campaigns: 5, mindbody_import: 5, at_risk_chaflow: 1, auto_close_conversations: 1 ], plugins: [ {Oban.Plugins.Cron, crontab: [{"59 11 * * SUN", Main.WeeklyReports}]} ]
该错误似乎与DynamicSupervisor
预期:strategy
选项有关,但我不确定如何解决它。
环境详情:
Elixir 版本:1.12.2
Oban版本:2.18.3
MacOS Sequoia:15.1.1
这里可能出了什么问题?如何修复此问题并让服务器重新运行?
非常感谢任何帮助或指导!
我正试图更新操作系统,然后就发生了这种情况
我的简单 LiveView 表单中有以下代码。
defmodule TodoappWeb.UserRegistrationLive do
alias Todoapp.Accounts
use TodoappWeb, :live_view
alias Todoapp.User
@impl true
def render(assigns) do
~H"""
<.form :let={f} id="registration-form" for={@form} phx-submit="save" phx-change="validate">
<h2 class="mt-6 text-center text-3xl font-extrabold text-gray-900">
Register
</h2>
<.input type="text" field={f[:firstname]} label="Firstname" />
<.input type="text" field={f[:middlename]} label="Middlename" />
<.input type="text" field={f[:lastname]} label="Lastname" />
<.input type="text" field={f[:email]} label="Email" />
<br />
<button
type="submit"
class="ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
>
Register
</button>
</.form>
<br />
<.link patch={~p"/users/login"}>Login</.link>
"""
end
@impl true
def mount(_params, _session, socket) do
form =
%User{}
|> User.changeset(%{})
|> to_form(as: "form")
{:ok, assign(socket, form: form)}
end
@impl true
def handle_event("save", %{"form" => params}, socket) do
case Accounts.register_user(params) do
{:ok, _user} ->
{:noreply,
socket
|> put_flash(:info, "User registered successfully!")
|> redirect(to: ~p"/users/login")}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply,
socket
|> put_flash(:error, "Registration failed. Please check the errors below.")
|> assign(form: to_form(changeset))}
end
end
@impl true
def handle_event("validate", %{"form" => params}, socket) do
form =
%User{}
|> User.changeset(params)
|> Map.put(:action, :validate)
|> to_form(as: "form")
{:noreply, assign(socket, form: form)}
# {:noreply, assign(socket, params: params)}
end
end
表单呈现良好,并且当字段为空时我会看到错误消息,但如果我在字段中输入一个值并将其删除,表单就会崩溃并出现以下错误:
[error] GenServer #PID<0.5544.0> terminating
** (FunctionClauseError) no function clause matching in TodoappWeb.UserRegistrationLive.handle_event/3
(todoapp 0.1.0) lib/todoapp_web/live/user_registration_live.ex:44: TodoappWeb.UserRegistrationLive.handle_event("validate", %{"_target" => ["user", "lastname"], "user" => %{"email" => "", "firstname" => "d", "lastname" => "", "middlename" => ""}}, #Phoenix.LiveView.Socket<id: "phx-GAnDLL8TB_56nzlF", endpoint: TodoappWeb.Endpoint, view: TodoappWeb.UserRegistrationLive, parent_pid: nil, root_pid: #PID<0.5544.0>, router: TodoappWeb.Router, assigns: %{form: %Phoenix.HTML.Form{source: #Ecto.Changeset<action: :insert, changes: %{firstname: "d", lastname: "d"}, errors: [email: {"can't be blank", [validation: :required]}], data: #Todoapp.User<>, valid?: false, ...>, impl: Phoenix.HTML.FormData.Ecto.Changeset, id: "user", name: "user", data: %Todoapp.User{__meta__: #Ecto.Schema.Metadata<:built, "users">, id: nil, firstname: nil, middlename: nil, lastname: nil, email: nil, inserted_at: nil, updated_at: nil}, action: :insert, hidden: [], params: %{"email" => "", "firstname" => "d", "lastname" => "d", "middlename" => ""}, errors: [email: {"can't be blank", [validation: :required]}], options: [method: "post"], index: nil}, __changed__: %{}, flash: %{"error" => "Registration failed. Please check the errors below."}, live_action: :new}, transport_pid: #PID<0.5537.0>, ...>)
不确定我做错了什么?
你好,我有这个结构
request = %Model{
id: 4_269_615,
site_id: 3,
user_id: 183_317,
program_id: 174,
type: %ProgramType{
value: :CASHBACK_PROGRAM,
__unknown_fields__: []
},
type_data: %ProgressProgramUser{
id: 1_336_676,
valid_stake: nil,
level: nil,
theo_ggr: nil,
__unknown_fields__: []
},
start_at: ~U[2024-09-05 13:27:20.391727Z],
end_at: nil,
inserted_at: ~U[2024-09-05 13:27:24.152602Z],
program_name: "test cb program 20 min GOLD NFT",
__unknown_fields__: []
}
我正在尝试__unknown_fields__: []
从结构以及嵌套结构中删除。
我正在使用的代码正在运行
def drop_unknown_fields(struct) when is_struct(struct) do
struct
|> Map.from_struct()
|> drop_unknown_fields()
end
def drop_unknown_fields(%{} = map) when is_map(map) do
map
|> Enum.reduce(%{}, fn {key, value}, acc ->
updated_value =
case date?(value) do
true -> value
false -> drop_unknown_fields(value)
end
Map.put(acc, key, updated_value)
end)
|> Map.delete(:__unknown_fields__)
end
def drop_unknown_fields(value), do: value
def date?(%DateTime{}), do: true
def date?(%Date{}), do: true
def date?(%NaiveDateTime{}), do: true
def date?(_), do: false
但我认为这不是正确的做法。检查日期的原因是:当我尝试执行嵌套结构时,数据时间也是一个结构,它会被解析为一个映射,而这并不是必需的。所以你能指导我一些清理这个结构并删除的最佳方法吗?:__unknown_fields__
谢谢
更新:我用下面的代码重构了它,但仍在寻找建议。
def drop_unknown_fields(struct) when is_struct(struct) do
struct
|> Map.from_struct()
|> only_consider_unknown_fields(struct)
|> drop_unknown_fields()
end
def drop_unknown_fields(%{} = map) when is_map(map) do
map
|> Enum.reduce(%{}, fn {key, value}, acc ->
updated_value = drop_unknown_fields(value)
Map.put(acc, key, updated_value)
end)
|> Map.delete(:__unknown_fields__)
end
def drop_unknown_fields({:consider, map}), do: drop_unknown_fields(map)
def drop_unknown_fields({:ignore, struct}), do: struct
def drop_unknown_fields(value), do: value
defp only_consider_unknown_fields(map, struct) do
case Map.has_key?(map, :__unknown_fields__) do
true -> {:consider, map}
false -> {:ignore, struct}
end
end
我正在抓狂,因为我知道我可能遗漏了一些非常小的东西,但我只是想在成功提交表单后清除表单——一个要点创建成功,没有任何问题。
这是我的简单的 create_gist_live.ex 文件:
defmodule ElixirGistWeb.CreateGistLive do
use ElixirGistWeb, :live_view
import Phoenix.HTML.Form
alias ElixirGist.{Gists, Gists.Gist}
def mount(_params, _session, socket) do
socket =
assign(
socket,
form: to_form(Gists.change_gist(%Gist{}))
)
{:ok, socket}
end
def handle_event("create", params, socket) do
case Gists.create_gist(socket.assigns.current_user, params["gist"]) do #passing params["gist"] is so so necessary. I was stuck for a day just passing params at first
{:ok, _gist} ->
changeset = Gists.change_gist(%Gist{})
socket =
socket
|> put_flash(:info, "Gist created successfully.")
|> assign(:form, to_form(changeset))
{:noreply, socket}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, :form, to_form(changeset))}
end
end
end
然后这是相应的.html.heex 文件:
<div class="em-gradient flex items-center justify-center">
<h1 class="font-brand font-bold text-3xl text-white">
Instantly share Elixir code, notes, and snippets.
</h1>
</div>
<.form for={@form} phx-submit="create">
<div class="justify-center px-28 w-full space-y-4 mb-10">
<.input field={@form[:description]} placeholder="Gist description.." autocomplete="off"/>
<div>
<div class="flex p-2 items-center bg-emDark rounded-t-md border">
<div class="w-[300px] mb-2">
<.input field={@form[:name]} placeholder="Filename including extension..." autocomplete="off"/>
</div>
</div>
<.input
field={@form[:markup_text]}
type="textarea"
placeholder="Insert code..."
spellcheck="false"
autocomplete="off"
/>
</div>
<div class="flex justify-end">
<.button class="create_button">Create gist</.button>
</div>
</div>
</.form>
表单正常工作,因为在填写所有字段后数据会持久保存到 postgres 数据库中。如果缺少字段,我们会收到验证错误。但我就是无法在成功提交后清除表单。我以为我做了正确的事情,即创建一个空白的 Gist 变更集并将其分配给表单,但由于某种原因,这不起作用。
我在下面的 ecto 中有这个查询:
query =
from(tx in Treatment,
join: ax in assoc(tx, :ax_sheet),
join: ev in assoc(ax, :visit),
join: evr in assoc(ev, :visit_revisions),
where: is_nil(tx.visit_revision_id),
where: not is_nil(ev.current_revision_id),
select: %{
id: tx.id,
visit_revision_id: coalesce(ev.current_revision_id, subquery(
from vr in VisitRevision,
where: vr.visit_id == ^ev.id and vr.inserted_at <= ^tx.marked_at,
order_by: [desc: vr.inserted_at],
limit: 1,
select: vr.id
))
}
)
我遇到一个问题,在下面这一行出现以下错误:
where: vr.visit_id == ^ev.id and vr.inserted_at <= ^tx.marked_at,
undefined variable ev
undefined variable tx
我的问题很简单。我该如何解决这个问题?我读到无法subquery
检索我之前在外部查询中定义的内容,那么我如何才能简单地传入我需要的 ID?我是 elixir 的新手,希望这是一个容易解决的问题之一。谢谢。
我的理解是,地图实现了收集器协议,因此可以用于into:
理解部分。为了尝试这个,我编写了以下程序:
lt = [{"ab", "cd", "ef"}, {"x", "y", "z"}]
m = %{}
for c <- lt, into: m do
IO.puts(length(Map.keys(m)))
{elem(c,1),elem(c,0)}
end
IO.puts(length(Map.keys(m)))
我预计这m
会在最后设定%{"cd" => "ab", "y" => "x"}
并看到
0
1
2
正在打印,但我打印了0
三遍。地图上似乎什么也没有收集到m
。为什么?
在 Elixir 中,我有以下列表:
[ :juridical_person_document, [re_developments: [[properties: [[re_development: [:re_developer]]]]]], :legal_address ]
我想要的输出是这样的:
[ :juridical_person_document, re_developments: [properties: [re_development: [:re_developer]]], :legal_address ]
换句话说,我想删除不必要的方括号。我怎样才能做到这一点?
我知道这可以通过递归来实现,但我还不知道如何实现。
所以,我有这个结构:
defmodule Card do
defstruct id: nil, result_numbers: [], owned_numbers: []
end
owned_numbers
对于每个实例,我计算其中的result_numbers
总数(CardEvaluator.evaluate_card()
该位经过测试并且有效)。
然后,我构建一系列值,其中(card.id + 1)..(card.id + value)
value 是卡片评估器返回的值。
然后,我想使用process_card_reward
该范围内每个索引中的卡递归调用我的方法。因此,如果卡 2 的值为 3,我会process_card_reward
用第三张、第四张和第五张牌跟注。然后我想总结制作的卡片总数。
我有这个:
def process_scratchcards(card_strings) do
cards =
card_strings
|> Enum.map(&CardParser.parse_card/1)
|> IO.inspect()
total_reward = cards
|> Enum.map(fn card -> process_card_reward(card, cards) end)
|> Enum.sum()
IO.puts(total_reward)
total_reward
end
def process_card_reward(card, all_cards) do
value =
card
|> CardEvaluator.evaluate_card()
victory_range = (card.id + 1)..(card.id + value)
IO.inspect(victory_range)
num_children =
Enum.reduce(victory_range, 0, fn n, acc ->
acc + process_card_reward(Enum.at(all_cards,n), all_cards)
end)
IO.puts(num_children)
num_children + 1
end
但是我遇到了这个我不明白的异常:
test 正确处理测试数据 (ScratchcardsTest) test/scratchcards_test.exs:5 ** (KeyError) key :owned_numbers not found in: nil
如果您使用点语法,例如 map.field,请确保点的左侧是映射代码: |> Scratchcards.process_scratchcards() stacktrace: (scratchcards 0.1.0) lib/card_evaluator.ex: 3: CardEvaluator.evaluate_card/1 (scratchcards 0.1.0) lib/scratchcards.ex:19: Scratchcards.process_card_reward/2 (scratchcards 0.1.0) lib/scratchcards.ex:26: Scratchcards.process_card_reward/2 中的匿名 fn/3 (elixir 1.15.7) lib/enum.ex:4379: Enum.reduce/3 (scratchcards 0.1.0) lib/scratchcards.ex:25: Scratchcards.process_card_reward/2 (scratchcards 0.1.0) lib/scratchcards.ex: 26:Scratchcards.process_card_reward/2 中的匿名 fn/3 (elixir 1.15.7) lib/enum.ex:4379: Enum.reduce/3 (scratchcards 0.1.0) lib/scratchcards.ex:25: Scratchcards.process_card_reward/2 (scratchcards 0.1.0) lib/scratchcards.ex:26: Scratchcards 中的匿名 fn/3。process_card_reward/2 (elixir 1.15.7) lib/enum.ex:4379: Enum.reduce/3 (scratchcards 0.1.0) lib/scratchcards.ex:25: Scratchcards.process_card_reward/2 (elixir 1.15.7) lib/enum .ex:1693: Enum."-map/2-lists^map/1-1-"/2 (scratchcards 0.1.0) lib/scratchcards.ex:9: Scratchcards.process_scratchcards/1 test/scratchcards_test.exs:18 : (测试)
我怎样才能解决这个问题?
使用默认生成的控制器,我收到以下警告。当我修改添加另一条路线时,我也收到了警告。显然我做错了什么,但从错误消息来看并不明显。
warning: HelloWeb.HelloWeb.PageController.init/1 is undefined (module HelloWeb.HelloWeb.PageController is not available or is yet to be defined)
lib/hello_web/router.ex:26: HelloWeb.Router.__checks__/0
我的搜索结果表明路由器中使用的控制器模块名称与实际定义的名称之间通常不匹配,但如果是这种情况,我无法检测到差异。
defmodule HelloWeb.Router do
alias HelloWeb.PageController
use HelloWeb, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_live_flash
plug :put_root_layout, html: {HelloWeb.Layouts, :root}
plug :protect_from_forgery
plug :put_secure_browser_headers
plug :fetch_current_user
end
scope "/", HelloWeb do
pipe_through :browser
# I should note that this line produces the following warning in VSCode using the Phoenix extension
# "HelloWeb.HelloWeb.PageController.init/1 is undefined (module HelloWeb.HelloWeb.PageController is not available or is yet to be defined)"
get "/", PageController, :home
end
defmodule HelloWeb.PageController do
use HelloWeb, :controller
def home(conn, _params) do
# The home page is often custom made,
# so skip the default app layout.
render(conn, :home, layout: false)
end
end
这里对我来说突出的是警告指的是HelloWeb.HelloWeb.PageController
尽管模块被命名为HelloWeb.PageController
. 我不知道差异的原因,或者即使它与实际问题有关。
init/1
?编辑:基于下面有用的解决方案,我发现 VSCode ElixirLS 扩展会在需要时默认插入别名,这会破坏 Phoenix 处理路由的方式。可以在扩展设置中禁用此功能:
缺点是禁用此功能似乎会破坏自动完成功能。