Newxan
Changing waffle filename implementation on the fly
Hi, I’m using waffle to upload files a s3 bucket. It’s been working well by I’ve decided I wan’t to change what names are used for the files. So i implement the filename/2 as follows:
# Override the persisted filenames:
def filename(version, {file, scope}) do
file_name = Path.basename(file.file_name, Path.extname(file.file_name))
"#{file_name}_#{version}_#{:os.system_time()}"
end
But now all my already uploaded files have incorrect references to them. Anyone know of a good way to do this, I guess I could just compare the files updated_at timestamp to see if it happend before or after the updated filename definition but I get the feeling I’m missing a more elegant solution.
Thanks in advance, any suggestions are appreciated ![]()
Most Liked
tangui
You might be interested in this issue on Github: Support dynamic file naming.
Had the same problem recently, you can also make the change of filename by tweaking the changeset (see https://github.com/elixir-waffle/waffle_ecto/issues/13) However, Waffle automatically added file extension and I gave up with this solution. Using the underlying ExAws.S3 is actually not hard and gives more flexibility if you don’t need advanced Waffle features.
Newxan
Thanks for your suggestions!
After banging my head against this trying to to find a safe and effective solution i decided to solve the problem outside of waffle. So in my controllers I now have a function that goes through the attachments in the parameters and adjusts the filenames in the different %Plug.Upload{}.
def unique_attachments(params, options \\ []) do
defaults = [
field: "attachments"
]
options = defaults |> Keyword.merge(options) |> Enum.into(%{})
attachments = Map.get(params, options.field, %{})
Enum.reduce(attachments, %{}, fn {key, value}, acc ->
case Map.get(value, "file", nil) do
nil ->
Map.put(acc, key, value)
file ->
filename = Map.fetch!(file, :filename)
unique_filename = "#{:os.system_time()}_#{filename}"
file = Map.put(file, :filename, unique_filename)
value = Map.put(value, "file", file)
Map.put(acc, key, value)
end
end)
end
It’s not elegant but it works and it does not risk corrupting my old existing attachments, since it will only apply to new files. ![]()
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








