Comments (9)
@chrisjowen I added a uuid to the change set directly in my ecto model it works well enough. I just check to only set it if its not already set. https://github.com/digitalcake/digitalcakes_tmp/blob/master/web/models/post.ex#L27
https://github.com/digitalcake/digitalcakes_tmp/blob/master/web/uploaders/imagable.ex#L29
from arc_ecto.
@DigitalCake do you still have those examples?
from arc_ecto.
To be honest I haven't worked with UUIDs in Ecto yet, and you're right. The use cases I have built Arc with were mostly geared towards adding attachments or images to existing models.
Given that, I am open to having a better workflow for uploading during creation of the model itself, but I haven't had the time to investigate what a clean implementation would look like.
If you can get Ecto to assign the UUID prior to cast_attachments
, then it should work fine. I don't know since I haven't tried though.
Alternatively, you can insert the model and then add the attachment immediately after, as in #7
from arc_ecto.
Hi Stavro,
Thanks for the advice, adding the id in the changeset prior to cast_attachments as another cast did work but would have implications to updates as it always sets the id field. This isnt a problem for me as I wont be updating but its not really ideal.
I don't wanna start branching and adding features you disagree with (if I even can, as I said i'm an elixir/ecto newbie). But I thought that it would be useful was if the result of arc's store method returned a map with the filename and a generated uuid or some other unique id to be used in the definition methods. This would avoid having to have the models id available, so things like this could be used in the definition:
def storage_dir(version, {file, scope}) do
# "uploads/#{scope.id}" -- in this case scope is model and on insert has no id
"uploads/#{file.file_identifier}"
end
This would need to be stored similar to the timestamp something like.
[image]|[UniqueIdentifier]?[Timestamp]
i.e. photo.jpg|c796ae4a-636f-4e03-9129-419ccdd47cdf?1234321
Not sure how you feel about such a solution, does it even make sense :) Whats your thoughts?
Chris
from arc_ecto.
@stavro So I had a stab at what I proposed, and it seems to work well for my use case. I'm hesitant to raise a PR both because my elixir skills suck and I was unsure if you even agreed with this idea. Anyway, for reference here are my forks:
master...chrisjowen:master
stavro/arc@master...chrisjowen:master
Summary is that Arc.File defstruct now has an identifier key. When its 'new' function is invoked it's given the value of a UUID. When Arc.Actions.Store.store is called it returns {file_name: xxx, identifier: xxx} instead of just the file name and arc_ecto uses this as I described before.
Chris
from arc_ecto.
@DigitalCake cheers I thought of this in the first place. But I didn't like the idea of manually having to add a unique identifier to my model. If I added more files to the model I'd end up having several file identifiers properties. I just wanted this to be handled for me.
from arc_ecto.
@DigitalCake I just went the same way and it worked perfectly. Thanks!
from arc_ecto.
@igorbelo Here is an example of model that works for me.
defmodule Hello.Client do
use Hello.Web, :model
use Arc.Ecto.Schema
schema "clients" do
field :name, :string
field :age, :integer
field :uuid, :string
field :avatar, Hello.Avatar.Type
timestamps()
end
@doc """
Builds a changeset based on the `struct` and `params`.
"""
def changeset(struct, params \\ %{}) do
struct
|> cast(params, [:name, :age, :uuid])
|> check_uuid
|> cast_attachments(params, [:avatar])
|> validate_required([:name, :age])
end
defp check_uuid(changeset) do
if get_field(changeset, :uuid) == nil do
force_change(changeset, :uuid, UUID.uuid1)
else
changeset
end
end
end
And the Hello.Avatar module
defmodule Hello.Avatar do
use Arc.Definition
use Arc.Ecto.Definition
def __storage, do: Arc.Storage.Local
@versions [:original, :thumb]
# Whitelist file extensions:
# def validate({file, _}) do
# ~w(.jpg .jpeg .gif .png) |> Enum.member?(Path.extname(file.file_name))
# end
# Define a thumbnail transformation:
def transform(:thumb, _) do
{:convert, "-strip -thumbnail 100x100^ -gravity center -extent 100x100 -format png", :png}
end
# Override the persisted filenames:
def filename(version, _) do
version
end
# Override the storage directory:
def storage_dir(version, {file, scope}) do
if scope do
"uploads/avatars/#{scope.uuid}"
end
end
# Provide a default URL if there hasn't been a file uploaded
# def default_url(version, scope) do
# "/images/avatars/default_#{version}.png"
# end
# Specify custom headers for s3 objects
# Available options are [:cache_control, :content_disposition,
# :content_encoding, :content_length, :content_type,
# :expect, :expires, :storage_class, :website_redirect_location]
#
# def s3_object_headers(version, {file, scope}) do
# [content_type: Plug.MIME.path(file.file_name)]
# end
end
from arc_ecto.
For anyone who comes here finding that they can't replace their attachment in a changeset:
you'll get the previous attachment (you can access it in your changeset via changeset.data
), delete it, and run another force_change(changeset, :uuid, UUID.uuid1) so that it knows it needs to upload this incoming file.
from arc_ecto.
Related Issues (20)
- 2 pictures in one schema HOT 1
- Ecto 3.0 emits warnings when using arc_ecto HOT 3
- arc_ecto not working with ecto 3 HOT 15
- Examples for saving arc photo from websocket? HOT 1
- Dialyzer error HOT 1
- Problem with Tests
- Support for signed Cloudfront web distributions.
- Specify Field Name In Scope
- Truncating updated_at broke my tests
- Cant get upload from frontend to work with Ecto 3 and arc_ecto in Phoenix API. HOT 1
- Uploading to S3 from a remote URL returns a SignatureDoesNotMatch error
- Fix Ecto 3.2 warnings HOT 3
- Adding or changing versions HOT 3
- Timout when transforming image HOT 1
- Upload via remote URL doesn't seem to work. HOT 1
- allow_urls feature to allow upload for valid URLs only HOT 1
- arc_ecto requires arc 0.8.0 HOT 1
- Error uploading to S3 with 0.10.0 HOT 2
- Microseconds in updated_at timestamp HOT 4
- Todo: Support Ecto 3 HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from arc_ecto.