我试图在凤凰城设置一个基本数据库,并且想要一个类似于Phoenix Ecto tutorial的Video
模型的模型 - 基本上使用has_many
- 以及与File Uploads tutorial类似的上传。
在我的情况下,我希望允许用户上传多个.csv,这些已添加到数据库中。现在我限制一个.csv上传创建一个用户专注于让那么多工作。我也不关心我将要存储的内容 - 现在是.csv所在的路径,只是为了简单起见。将来我可能想直接存储csv数据。
我在user_params中获取%Plug.Upload,并且能够将其写入文件,但我不确定如何将该路径添加到数据库中。
最新错误发生在用户/模型中(见下文)。
这是我到目前为止所拥有的:
模型/ csv.ex
defmodule Test.CSV do
use Test.Web, :model
schema "csvs" do
field :csv, {:array, :string}
belongs_to :user, Test.User
timestamps()
end
...
模型/ user.ex
defmodule Test.User do
use Test.Web, :model
schema "users" do
field :uname, :string
field :group, :string
has_many :csvs, Test.CSV
timestamps()
end
def changeset(struct, params \\ %{}) do
struct
|> cast(params, [:uname, :group])
# Wasn't sure what else to do here. Currently throws an error at this line with 'protocol Enumerable not implemented for %Plug.Upload{...filename...etc.}'.
# I figure I probably need to specify somewhere that I only want a certain field, like the path, but I'm not sure how to do that.
|> cast_assoc([:csvs])
|> validate_required([:uname, :group])
end
user_controller.ex
...
def create(conn, %{"user" => user_params}) do
changeset = User.changeset(%User{}, user_params)
case Repo.insert(changeset) do
{:ok, _user} ->
conn
|> put_flash(:info, "User created successfully.")
|> redirect(to: user_path(conn, :index))
{:error, changeset} ->
render(conn, "new.html", changeset: changeset)
end
end
...
用户/ forms.html.eex
<%= form_for @changeset, @action, [multipart: true], fn f -> %>
...
<%= inputs_for f, :csvs, fn i -> %>
<div class="form-group">
<label>CSV</label>
<%= file_input i, :csv, class: "form-control" %>
</div>
<% end %>
...
<% end %>
我还确保我做了ecto.migrate
并将csvs表添加到数据库中。
def change do
alter table(:users) do
# Hmm, not sure if that should have been a :map.
add :csvs, :map
end
end
然后我是否应该使用嵌套关联(正确的术语?),或者使用嵌入式模式的路径。毋庸置疑,我是凤凰城的新手,非常感谢有关如何解决这个问题的任何想法。谢谢!
答案 0 :(得分:0)
我真的很惊讶你是如何在模式{:array, :string}
中使用这种表示法的...对你的案例最简单的解决方案是在has_many
之间建立User
关系和CSV
这部分你有效。
现在由您决定如何在数据库中存储有关这些CSV的信息 - 如果您处理Plug.Upload它只不过是文件,但您需要自定义Ecto的方式使用Ecto.Type处理此类型,因为file是一个复杂的结构。
另一种选择是解析该CSV文件,然后将其放入CSV
表并将其与User
关联,可能最好的方法是使用CSV插件读取内容文件 - CSVLixir或任何其他文件 - 并将其与put_assoc
合并。
就我个人而言,我不会在数据库中存储整个文件,但会引用它,例如。文件名和内容(如果需要)。