标签: phoenix-framework

protocol nume(phoenix-framework)无法实现

我在订单控制器中添加了一个功能"付款",并添加了一个路由.

def payment(conn, %{"id" => id}) do
  foods = Repo.all(Food)
  order =
    Repo.get!(assoc(conn.assigns[:table], :orders), id)
    |> Repo.preload(order_items: :food)
  order_item_changeset =
    order
    |> build_assoc(:order_items)
    |> Pos1.OrderItem.changeset()
  order_changeset = Order.changeset(order)

  render(conn, "payment.html", order: order, order_item_changeset: order_item_changeset, order_changeset: order_changeset, foods: foods, payment: @payment)
end

resources "/tables", TableController do
  resources "/orders", OrderController do
    get "/payment", OrderController, :payment
end
Run Code Online (Sandbox Code Playgroud)

我在表和订单下添加了付款路线,因为付款必须显示其表号和订单ID.我在show.html的订单模板中添加了指向付款页面的链接.但是,它会导致Protocol.UndefinedError.

[error] #PID<0.9096.0> running Pos1.Endpoint terminated
Server: localhost:4000 (http)
Request: GET /tables/1/orders/14
** (exit) an exception was raised:
    ** (Protocol.UndefinedError) protocol Enumerable not implemented for nil …
Run Code Online (Sandbox Code Playgroud)

elixir phoenix-framework

0
推荐指数
1
解决办法
3537
查看次数

Phoenix默认的json日期在Chrome/Firefox中的解析方式不同

我正在尝试以timestamp inserted_atjson的形式提供自动字段.

问题是Chrome和Firefox在分析发送内容方面存在分歧.问题似乎是菲尼克斯默认提供的服务"2017-01-12T19:49:000".这由Firefox和IE解析为UTC,而Chrome将此转换为本地时间.添加一个Z("2017-01-12T19:49:000Z"),所有都给当地时间.

结果我将我的代码转换为:

def render("message.json", %{message: message}) do
    %{id: message.id,
      content: message.content,
      date: Ecto.DateTime.to_iso8601(message.inserted_at)<>"Z"}
end
Run Code Online (Sandbox Code Playgroud)

但这感觉非常黑客,必须有一个更好的方法.

elixir ecto phoenix-framework

0
推荐指数
1
解决办法
130
查看次数

创建几乎完全相同的2个插头,但略有不同

我有自己的插头模块:

defmodule Module1 do

  def init(opts) do
    opts
  end

  def call(conn, _opts) do
    # if some_condition1
    # something
  end

  # other stuff
end
Run Code Online (Sandbox Code Playgroud)

在router.ex中

  pipeline :pipeline1 do
    plug(Module1)
  end

  scope "/scope", MyApp, as: :scope1 do
    pipe_through([:browser, :pipeline1])
    # .......
Run Code Online (Sandbox Code Playgroud)

现在我想使用相同的模块Module1创建第二个管道和范围:

  pipeline :pipeline2 do
    plug(Module1)
  end

  scope "/scope2", MyApp, as: :scope2 do
    pipe_through([:browser, :pipeline2])
    # .......
Run Code Online (Sandbox Code Playgroud)

但是,如果我要创建第二个模块,那么区别仅在于:

 def call(conn, _opts) do
    # if some_condition1 and some_condition2
    # something
  end
Run Code Online (Sandbox Code Playgroud)

也就是说,我只添加了"some_condition2",其他一切都保持不变.

现在,我该怎么做?我是否必须创建与Module1完全相同的模块Module2并轻轻地更改"call"?它会导致代码重复.

elixir phoenix-framework

0
推荐指数
1
解决办法
35
查看次数

如何在phoenix elixir聊天应用程序中监控树中运行Redix并从不同模块访问

我想在我的聊天应用程序中使用{:redix,"〜> 0.6.1"} hex包,并从监督树开始

{:ok, conn} = Redix.start_link()
{:ok, conn} = Redix.start_link(host: "example.com", port: 5000)
{:ok, conn} = Redix.start_link("redis://localhost:6379/3", name: :redix)


Redix.command(conn, ["SET", "mykey", "foo"])
Run Code Online (Sandbox Code Playgroud)

但是当我尝试将连接开始链接放到子进程时它会出错

children = [
      # Start the Ecto repository
      supervisor(PhoenixChat.Repo, []),
      # Start the endpoint when the application starts
      supervisor(PhoenixChat.Endpoint, []),
      # Start your own worker by calling: PhoenixChat.Worker.start_link(arg1, arg2, arg3)
      # worker(PhoenixChat.Worker, [arg1, arg2, arg3]),
      supervisor(PhoenixChat.Presence, []),

      #supervisor(Phoenix.PubSub.Redis, [:chat_pubsub, host: "127.0.0.1"])
    ]
Run Code Online (Sandbox Code Playgroud)

如何启动redix连接并将数据存储到Redis?

elixir redis elixir-framework phoenix-framework

0
推荐指数
1
解决办法
873
查看次数

模块 Ecto.Query 未加载且无法找到

我正在尝试按照 Programming Phoenix 的书中的示例练习通过 elixir shell 导入 Ecto.Query,它给了我这个错误

iex> import Ecto.Query

** (CompileError) iex:3: module Ecto.Query is not loaded and could not be found
Run Code Online (Sandbox Code Playgroud)

有人知道这是否已被弃用或是否有其他方式导入它?

elixir phoenix-framework

0
推荐指数
1
解决办法
1969
查看次数

如何使用过多的嵌套来重构case语句

在许多情况下,我发现自己需要在结构本身及其字段上进行模式匹配,并在某些中间结果不为空时继续执行一些进一步的操作.

但是,结构本身可能是nil第一位的.这导致我编写了多个嵌套匹配,例如

experiment = Repo.get(Experiment, experiment_id)

case experiment do
  nil ->
    # Error 1

  _ ->
    case experiment.active do
      false -> # Error 2
      true -> 
        case Repo.all(assoc(experiment, :experiment_results)) do
          [] -> # Error 3
          results -> # Do stuffs
    end
end
Run Code Online (Sandbox Code Playgroud)

理想情况下,我想编写没有那么多嵌套的代码.

我该如何重构代码?


(请注意,我原来的问题是关于结构上的模式匹配nil.我的实际用例比我原来提出的问题更广泛,因此我更新了问题.)

原始代码,AlekseiMatiushkin和Sheharyar的答案适用于:

experiment = Repo.get(Experiment, experiment_id)

case experiment do
  nil ->
    :error

  _ ->
    case experiment.active do
      false -> :error
      true -> # Do stuffs
    end
end
Run Code Online (Sandbox Code Playgroud)

functional-programming elixir pattern-matching phoenix-framework

0
推荐指数
1
解决办法
71
查看次数

Phoenix 似乎正在按字母顺序重新排序参数和模式匹配 - 这正常吗?

这是发送请求的前端代码 - 注意参数的顺序:

params = {ticket_guid: "XXX-XXX", user_name: "David", quantity: 2}
$.get('/init_stripe_transaction', params, function(data) {
Run Code Online (Sandbox Code Playgroud)

这是浏览器开发控制台中的“错误请求”数据,显示了参数的顺序:

http://localhost:4000/init_stripe_transaction?ticket_guid=XXX-XXX&user_name=David&quantity=2
Run Code Online (Sandbox Code Playgroud)

这是终端(服务器端)的错误响应,即phoenix elixir def logs。注意 - 由于某种原因,参数的顺序现在如何更改:

[info] GET /init_stripe_transaction
[debug] Processing with DiceWeb.TransactionController.create_stripe_session/2

Parameters: %{"quantity" => "2", "ticket_guid" => "XXX-XXX", "user_name" => "David"}
Pipelines: [:browser]
[info] Sent 400 in 357ms
[debug] ** (Phoenix.ActionClauseError) no function clause matching in DiceWeb.TransactionController.create_stripe_session/2 
Run Code Online (Sandbox Code Playgroud)

这就是我在控制器中进行模式匹配的方式:

def create_stripe_session(
  conn, 
  %{ticket_guid: ticket_guid, user_name: user_name, quantity: quantity}
) do ...
Run Code Online (Sandbox Code Playgroud)

额外参考:我对长生不老药/模式匹配很陌生。因此,决定堆栈溢出比在 phoenix 存储库上创建问题要好。这样模式匹配可以吗?

elixir phoenix-framework

0
推荐指数
1
解决办法
170
查看次数

如何使用 ecto 计算 2 列值

我想像下面的 SQL 一样用 ecto 计算 2 列值

SELECT goal, assist, (goal + assist) as point
FROM game
Run Code Online (Sandbox Code Playgroud)

我想添加带有目标+辅助列的点列。请给我一个建议。

elixir ecto phoenix-framework

0
推荐指数
1
解决办法
71
查看次数

在 Elixir 中编写以下逻辑的惯用方法是什么?

我有一个端点check200如果请求包含有效的则返回响应auth_token401否则返回。

def check(conn, _) do
  if auth_token = get_session(conn, :auth_token) do
    send_resp(conn, 200, "")
  end

  send_resp(conn, 401, "")
end
Run Code Online (Sandbox Code Playgroud)

这在auth_tokenis的情况下工作正常nil,但是,对于定义它的情况,我收到了一个奇怪的错误。

[error] Ranch listener AppWeb.Endpoint.HTTP had connection process started with :cowboy_clear:start_link/4 at #PID<0.6370.0> exit with reason: {:function_clause, [{:cowboy_http, :commands, [{:state, #PID<0.5887.0>, AppWeb.Endpoint.HTTP, #Port<0.1651>, :ranch_tcp, :undefined, %{env: %{dispatch: [{:_, [], [{:_, [], Phoenix.Endpoint.Cowboy2Handler, {AppWeb.Endpoint, []}}]}]}, stream_handlers: [Plug.Cowboy.Stream]}, "", %{}, {{127, 0, 0, 1}, 61063}, {{127, 0, 0, 1}, 4000}, :undefined, …
Run Code Online (Sandbox Code Playgroud)

elixir phoenix-framework

0
推荐指数
1
解决办法
149
查看次数

僵尸进程或类似的东西?

我有一个凤凰应用程序。有时我会遇到这样的情况:

$ ps aux
===>

user1    67297   0.0  0.2  13240  1860  -  S    Thu07       0:03.00 /usr/home/user1/my_projects/project1/erts-10.3.5.19/bin/epmd -daemon
Run Code Online (Sandbox Code Playgroud)

然后我会试着阻止它

$ MIX_ENV=prod ./bin/project1 stop
--rpc-eval : RPC failed with reason :nodedown
Run Code Online (Sandbox Code Playgroud)

为什么它首先说它已关闭?

尽管如此,它仍然会保持不变:

$ ps aux
===>

user1    67297   0.0  0.2  13240  1860  -  S    Thu07       0:03.00 /usr/home/user1/my_projects/project1/erts-10.3.5.19/bin/epmd -daemon
Run Code Online (Sandbox Code Playgroud)

怎么了?

PS 通常,有 3 个左右的进程与项目有关,尽管在我的问题中只有 1 个。在这种情况下,我已经通过“kill”手动杀死了其中的 2 个。然而,这并没有解决这个问题。

elixir phoenix-framework

0
推荐指数
1
解决办法
41
查看次数