Parameters Phoenix控制器中的参数结构
我在凤凰城创建了一个简单的“东西”外胚层模型。“图像”是一个字符串,它引用上传的文件。当上传的图像点击控制器时,我想将图像结构转换为字符串(为了本例,让我们将其另存为“foo123”)Parameters Phoenix控制器中的参数结构,parameters,elixir,phoenix-framework,ecto,changeset,Parameters,Elixir,Phoenix Framework,Ecto,Changeset,我在凤凰城创建了一个简单的“东西”外胚层模型。“图像”是一个字符串,它引用上传的文件。当上传的图像点击控制器时,我想将图像结构转换为字符串(为了本例,让我们将其另存为“foo123”) #/web/models/thing.ex defmodule MyApp.Thing do use MyApp.Web, :model schema "comics" do field :number, :integer field :image, :string times
#/web/models/thing.ex
defmodule MyApp.Thing do
use MyApp.Web, :model
schema "comics" do
field :number, :integer
field :image, :string
timestamps()
end
def changeset(struct, params \\ %{}) do
struct
|> cast(params, [:number, :image])
|> validate_required([:number, :image])
end
end
def create(conn, %{"thing" => thing_params}) do
IO.inspect thing_params
changeset = Thing.changeset(%Thing{}, thing_params)
|> change("image", "foo123") ### something like this
case Repo.insert!(changeset) do
{:ok, _thing} ->
conn
|> put_flash(:info, "Thing created successfully.")
|> redirect(to: thing_path(conn, :index))
{:error, changeset} ->
conn
|> put_flash(:error, "Something went wrong")
|> redirect(to: thing_path(conn, :index))
end
end
#/web/controllers/thing_controller.ex
defmodule MyApp.Thing do
use MyApp.Web, :model
schema "comics" do
field :number, :integer
field :image, :string
timestamps()
end
def changeset(struct, params \\ %{}) do
struct
|> cast(params, [:number, :image])
|> validate_required([:number, :image])
end
end
def create(conn, %{"thing" => thing_params}) do
IO.inspect thing_params
changeset = Thing.changeset(%Thing{}, thing_params)
|> change("image", "foo123") ### something like this
case Repo.insert!(changeset) do
{:ok, _thing} ->
conn
|> put_flash(:info, "Thing created successfully.")
|> redirect(to: thing_path(conn, :index))
{:error, changeset} ->
conn
|> put_flash(:error, "Something went wrong")
|> redirect(to: thing_path(conn, :index))
end
end
这不起作用,我仍然需要转换%{“image”=>%Plug。将{content_type:“image/jpeg”,…
上传到“foo123”,但这在哪里发生?在变更集分配中?在def create()
的参数中
另外,我如何才能
IO.inspect
仅仅检查param结构的某个成员?(例如,IO.inspect thing_params.image
?当多部分到达控制器时,Plug.Upload已经处理了下载并将其放入临时文件中。该文件名可以在%Plug.Upload{}中找到
struct。由您选择要使用的名称,将该文件复制到渗透位置。然后您可以将该名称放入图像字段或架构中。您必须在控制器中执行此操作,因为一旦请求结束,该文件将被删除
我建议您看看。它在处理文件附件方面做得很好,并提供了很好的API,用于将URL放入您的视图中
您还可以插入图像处理来创建Thubnail等。这是我处理图像和视频上传的一段代码。对于图像,我保存了完整的分辨率和海报大小的视图(用于在聊天应用程序中显示)。对于视频,我创建了海报图像,用于在聊天应用程序中显示视频
defmodule UcxChat.File do
use Arc.Definition
# Include ecto support (requires package arc_ecto installed):
use Arc.Ecto.Definition
require Logger
def __storage, do: Arc.Storage.Local
@versions [:original, :poster]
@acl :public_read
# To add a thumbnail version:
# @versions [:original, :thumb]
# Whitelist file extensions:
def validate({file, _}) do
~w(.jpg .jpeg .gif .png .txt .text .doc .pdf .wav .mp3 .mp4 .mov .m4a .xls) |> Enum.member?(Path.extname(file.file_name))
end
def transform(:poster, {_, %{type: "video" <> _}}) do
{:ffmpeg, fn(input, output) ->
"-i #{input} -f image2 -ss 00:00:01.00 -vframes 1 -vf scale=-1:200 #{output}" end, :jpg}
end
def transform(:poster, {_, %{type: "image" <> _}}) do
{:convert, "-strip -resize @80000 -format png", :png}
end
def filename(:poster, _params) do
:poster
end
def filename(_version, {_, %{file_name: file_name}}) do
String.replace(file_name, ~r(\.[^/.]+$), "")
end
def filename(_version, %{file_name: file_name}) do
file_name
end
def storage_dir(_version, {_file, scope}) do
storage_dir(scope)
end
def storage_dir(scope) do
path = "priv/static/uploads/#{scope.message_id}"
if UcxChat.env == :prod do
Path.join(Application.app_dir(:ucx_chat), path)
else
path
end
end
end
defmodule UcxChat.File do
使用弧定义
#包括外部支持(需要安装包arc\U外部):
使用Arc.exto.Definition
需要记录器
定义存储,do:Arc.storage.Local
@版本[:原件,:海报]
@acl:public\u read
#要添加缩略图版本,请执行以下操作:
#@versions[:original,:thumb]
#白名单文件扩展名:
def验证({file,})do
~w(.jpg.jpeg.gif.png.txt.text.doc.pdf.wav.mp3.mp4.mov.m4a.xls)|>Enum.member?(Path.extname(file.file_name))
结束
def转换(:poster,{},%%{type:“video”{})do
{:ffmpeg,fn(输入,输出)->
“-i{input}-f image2-ss00:00:01.00-vframes 1-vf scale=-1:200{output}”结束,:jpg}”
结束
def转换(:poster,{{},%%{type:“image”{})do
{:convert,“-strip-resize@80000-format png”,:png}
结束
def文件名(:海报,_参数)do
:海报
结束
def文件名(_版本,{{{,%%{file_name:file_name}})do
String.replace(文件名,~r(\.[^/]+$),“”)
结束
def文件名(_版本,%{file_name:file_name})do
文件名
结束
def storage_dir(_version,{u file,scope})do
存储目录(范围)
结束
def存储目录(范围)do
path=“priv/static/uploads/#{scope.message_id}”
如果UcxChat.env==:prod do
Path.join(Application.app\u dir(:ucx\u chat),Path)
其他的
路径
结束
结束
结束
即使你不想使用这个软件包,它可能会给你一些关于如何扮演自己角色的想法。对于最后一个问题,你可以做
IO.inspect thing_params[“image”]
。image
不起作用,因为键是一个字符串,而不是一个原子。对于主要问题,你可以使用>put_change(:image,“foo123”)
但这不会重新运行Thing.changeset/2
的验证。我不确定手动处理文件上传的最佳方式是什么,所以我只是在这里发表评论,而不是发布答案。@Dogbert这实际上是我在寻找的答案。put\u change()去哪里了?当我运行changeset=Thing.changeset(%Thing{},thing_params)|>放置更改(:image,“foo123”)
,我得到**(编译器错误)web/controllers/thing\u controller.ex:19:undefined function put\u change/3
。这是放错位置了吗,还是我忘了将某些内容导入控制器?@Dogbert:这正是我要找的,谢谢。如果你想发布此内容,我会将其标记为正确。`changeset=thing.changeset(%Comic{},Comic\u params)|>exto.Changeset.put_change(:image,“foo123”)`谢谢Steve!我尝试过arc_-exto,我喜欢它,但实际上我使用的是ex_aws,因为我正在部署Heroku,并且必须使用S3 bucket。即使我计划完全外包文件托管,arc_-exto还有其他选择吗?