我在Elixir项目中整合协议实现时遇到问题.更具体地说,我使用了Ecto一些简单的项目Gold(无关紧要).问题是,它们(Ecto和Gold)都Poison用于序列化Decimals(并实现适当的协议).
Ecto外观的实现有点像这样:
defimpl Poison.Encoder, for: Decimal do
def encode(decimal, _opts), do: <<?", Decimal.to_string(decimal)::binary, ?">>
end
Run Code Online (Sandbox Code Playgroud)
在开发期间,有一个警告说该模块是重复的:
warning: redefining module Poison.Encoder.Decimal (current version loaded from /(...)/_build/dev/lib/gold/ebin/Elixir.Poison.Encoder.Decimal.beam)
lib/ecto/poison.ex:2
Run Code Online (Sandbox Code Playgroud)
但是当我尝试使用例如exrm构建版本时,我会收到错误,说我有duplicate_modules
===> Provider (release) failed with: {error,
{rlx_prv_assembler,
{release_script_generation_error,
systools_make,
{duplicate_modules,
[{{'Elixir.Poison.Encoder.Decimal',
gold,
"/(...)/rel/bitcoin_api/lib/gold-0.12.0/ebin"},
{'Elixir.Poison.Encoder.Decimal',
ecto,
"/(...)/rel/bitcoin_api/lib/ecto-2.0.2/ebin"}}]}}}}
Run Code Online (Sandbox Code Playgroud)
我应该怎么处理这个?这里的情况是我实际使用我自己的版本Gold,所以我可以篡改它来尽快解决它.我知道我可以再补充Ecto到Gold作为依赖,但似乎有点矫枉过正,只是实现一个协议是这样的.是否有某种宏来检查模块是否已经实现?
我正在使用Poison将地图编码为JSON,并将其发送到Slack API.这就是Poison给我的东西:
"{\"text\":\"changed readme fad996e98e04fd4a861840d92bdcbbcb1e1ec296\"}"
Run Code Online (Sandbox Code Playgroud)
当我把它放入JSON lint时,它说它是有效的JSON,但是Slack响应"无效的有效载荷".
如果我将JSON更改为这样
{"text":"changed readme fad996e98e04fd4a861840d92bdcbbcb1e1ec296"}
Run Code Online (Sandbox Code Playgroud)
然后它工作.有谁知道我在哪里出错?我是否需要对编码的JSON进行额外处理,或者是否需要设置一些标头?
这是我的控制器
def create(conn, opts) do
message = Message.create_struct(opts)
response = Slack.Messages.send(message)
case response do
{:ok, data} ->
render conn, json: Poison.encode!(data)
{:error, reason} ->
render conn, json: reason
end
end
Run Code Online (Sandbox Code Playgroud)
这是发送消息的库的一部分
defmodule Slack.Messages do
def format_simple_message(map) do
text = map.description <> " " <> map.commits
message = %{text: text}
end
def post_to_slack(map) do
Slack.post(:empty, map)
end
def send(map) do
map
|> format_simple_message
|> post_to_slack
end
end
Run Code Online (Sandbox Code Playgroud)
我的HTTPoison处理
defmodule …Run Code Online (Sandbox Code Playgroud) ab = %{a: 1}
ac = %{"a" => 1}
Run Code Online (Sandbox Code Playgroud)
究竟有什么区别?为什么Poison.decode!返回格式#2(我需要#1与Ecto.Changeset.change一起使用).
Json响应来自API,看起来像
[{"a":3}]
Run Code Online (Sandbox Code Playgroud) 出于阅读目的,我想在json文件中有一个特定的键顺序.
我知道地图的密钥没有任何顺序,然后我们不应该依赖它,但由于Poison无法编码支持者,我不知道如何做到这一点.
iex(1)> %{from: "EUR", to: "USD", rate: 0.845} |> Poison.encode!
"{\"to\":\"USD\",\"rate\":0.845,\"from\":\"EUR\"}"
Run Code Online (Sandbox Code Playgroud)
我想要的结果是:
"{\"from\":\"EUR\", \"to\":\"USD\", \"rate\":0.845}"
Run Code Online (Sandbox Code Playgroud)
我应该使用哪种结构来实现毒药?
我已经使用 Posion.decode 解析了以下 JSON!
json = %{"color-Black|size:10" =>
%{"attributes" => %{"color" => "Black","size" => "11"},
"isAvailable" => true,
"pricing" => %{"standard" => "$415.00", "sale" => 415}},
"color|size-EU:9.5" =>
%{"attributes" => %{"color" => "Black","size" => "11"},
"isAvailable" => true,
"pricing" => %{"standard" => "$415.00", "sale" => 415}}}
Run Code Online (Sandbox Code Playgroud)
我想映射它,但随着节点元素中的文本发生变化,我无法获取 JSON 元素。到目前为止我已经尝试过了。
Enum.map(json , fn(item) ->
%{
color: item.attributes["color"],
size: item.attributes["size"],
price: item.pricing["standard"] * 100,
isAvailable: item.isAvailable
}
end)
Run Code Online (Sandbox Code Playgroud)
但是这段代码给出了一些与访问相关的错误。
我正在使用phoenix作为JSON API。我的模型之一如下所示,除非unique_constraint检查失败,否则它将很好地工作。发生这种情况时,我会收到以下错误消息:
(Poison.EncodeError) unable to encode value: {"Email address is already registered", []}
Run Code Online (Sandbox Code Playgroud)
型号:
defmodule MyApp.Registration do
use MyApp.Web, :model
@derive {Poison.Encoder, only: [:name, :email, :category]}
schema "registrations" do
field :name, :string
field :category, :string
field :email, :string
timestamps
end
def changeset(model, params \\ :empty) do
model
|> cast(params, ~w(name email category), [])
|> validate_length(:name, min: 1, max: 240)
|> unique_constraint(:email, message: "Email address is already registered")
end
end
Run Code Online (Sandbox Code Playgroud)
控制器:
def create(conn, registration_params) do
changeset = Registration.changeset(%Registration{}, registration_params) …Run Code Online (Sandbox Code Playgroud) 我正在尝试在Elixir中为API编写一个CLI客户端,以便我可以登录API系统,获取计算所需的数据,然后注销.我已经定义了一个Packet.Login结构,它应该是我在解析我收到的JSON后最终得到的内部数据结构.
我正在使用Poison来解析JSON.问题是,似乎,由于API返回大写属性,我在打印或解析时无法匹配它们,因为Poison将返回带有这些大写键的地图.问题是我似乎不可能使用这样的别名.如果我尝试使用其他语法,
packet[:Token]
Run Code Online (Sandbox Code Playgroud)
它仍然不起作用,而是给我一个错误.但这次关于Packet.Login没有实现Access行为.我能理解这一部分,但不是第一个问题.而我正试图保持代码愚蠢的简单.
defmodule Packet.Login do
defstruct [:Data, :Token]
end
defimpl String.Chars, for: Packet.Login do
def to_string(packet) do
"Packet:\n---Token:\t\t#{packet.Token}\n---Data:\t#{packet.Data}"
end
end
loginPacket = Poison.decode!(json, as: %Packet.Login{})
IO.puts "#{loginPacket}"
Run Code Online (Sandbox Code Playgroud)
在尝试编译上面的时候我得到了这个:
** (CompileError) lib/packet.ex:31: invalid alias: "packet.Token". If you wanted to define an alias, an alias must expand to an atom at compile time but it did not, you may use Module.concat/2 to build it at runtime. If instead you wanted to invoke a function or access a field, wrap the …Run Code Online (Sandbox Code Playgroud) 我正在尝试用毒药对这个字符串元组进行编码:
{"product existed but could not add categories to product",
"Shop existed but could not add product to shop"}
Run Code Online (Sandbox Code Playgroud)
出现此错误:
19:10:21.593 [error] #PID<0.339.0> running Api.Router terminated
Server: 192.168.20.3:4000 (http)
Request: POST /products
** (exit) an exception was raised:
** (Poison.EncodeError) unable to encode value: {"product existed but could not add categories to product", "Shop ex
isted but could not add product to shop"}
(poison) lib/poison/encoder.ex:383: Poison.Encoder.Any.encode/2
(poison) lib/poison/encoder.ex:227: anonymous fn/4 in Poison.Encoder.Map.encode/3
(poison) lib/poison/encoder.ex:228: Poison.Encoder.Map."-encode/3-lists^foldl/2-0-"/3
(poison) lib/poison/encoder.ex:228: Poison.Encoder.Map.encode/3
(poison) lib/poison.ex:41: …Run Code Online (Sandbox Code Playgroud) 我正在使用HTTPoisonElixir 进行网络请求:
HTTPpoison.post "http://localhost:3000/mymodels"," {\"param1\": \"#{value1}\" , \"param2\":\"#{value2}\"} ", [{"Content-Type", "application/json"}]
Run Code Online (Sandbox Code Playgroud)
这是我得到的回应:
{:ok,
%HTTPoison.Response{body: "{\"id\":46,\"result\":18,\"param1\":\"liqueur\",\"param2\":\"quif\"}",
headers: [{"X-Frame-Options", "SAMEORIGIN"},
{"X-XSS-Protection", "1; mode=block"}, {"X-Content-Type-Options", "nosniff"},
{"Location", "http://localhost:3000/mymodels/46"},
{"Content-Type", "application/json; charset=utf-8"},
{"ETag", "W/\"05b8c75e0a5288c835651f48d4b8a80a\""},
{"Cache-Control", "max-age=0, private, must-revalidate"},
{"X-Request-Id", "1e8ae2d3-073a-4779-916a-edffc38f8b5a"},
{"X-Runtime", "0.530440"}, {"Transfer-Encoding", "chunked"}],
status_code: 201}}
Run Code Online (Sandbox Code Playgroud)
我是Elixir的新手,我的问题是我想从中得到results元素response.body
iex(3)> response.body
"{\"id\":46,\"results\":18,\"param1\":\"liqueur\",\"param2\":\"quif\"}"
Run Code Online (Sandbox Code Playgroud)
我不知道如何将此字符串转换为Elixir中的数组/哈希或stuple.我在Enum,但似乎没有用