Skip to content

Instantly share code, notes, and snippets.

@kainlite
Created July 8, 2016 19:37
Show Gist options
  • Save kainlite/58202fbffbe948ad240cfd3967e75c71 to your computer and use it in GitHub Desktop.
Save kainlite/58202fbffbe948ad240cfd3967e75c71 to your computer and use it in GitHub Desktop.
def update_profile_picture(conn, params) do
current_user = MyApp.Session.current_user(conn)
changeset = User.image_changeset(current_user, %{avatar: params["avatar"]})
case Repo.update(changeset) do
{:ok, user} ->
render(conn, "show.json", user: user, jwt: Guardian.Plug.current_token(conn))
{:error, changeset} ->
conn
|> put_status(:unprocessable_entity)
|> render(MyApp.ChangesetView, "error.json", changeset: changeset)
end
end
# Error:
# Ecto.Changeset<action: nil, changes: %{},
# errors: [avatar: {"is invalid", [type: MyApp.Avatar.Type]}],
# data: #MyApp.User<>, valid?: false>
defmodule MyApp.Avatar do
use Arc.Definition
use Arc.Ecto.Definition
# Include ecto support (requires package arc_ecto installed):
use Arc.Ecto.Definition
# To add a thumbnail version:
@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 250x250^ -gravity center -extent 250x250 -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
"uploads/avatars/#{scope.id}"
end
# def __storage, do: Arc.Storage.Local
def __storage, do: Arc.Storage.S3
def filename(version, {file, scope}), do: "#{version}-avatar"
# Provide a default URL if there hasn't been a file uploaded
def default_url(version, scope) do
"/images/avatars/profile_default.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
defmodule MyApp.User do
use MyApp.Web, :model
use Ecto.Schema
use Arc.Ecto.Schema
schema "users" do
field :first_name, :string
field :last_name, :string
field :role, :string
field :email, :string
field :password, :string, virtual: true
field :encrypted_password, :string
field :avatar, MyApp.Avatar.Type
timestamps
end
@derive {Poison.Encoder, only: [:id, :first_name, :last_name, :email, :role, :avatar]}
@required_fields ~w(first_name last_name role email password)a
@optional_fields ~w(activation_state activation_token)a
@required_file_fields ~w()a
@optional_file_fields ~w(avatar)a
@doc """
Creates a changeset based on the `data` and `params`.
If no params are provided, an invalid changeset is returned
with no validation performed.
"""
def changeset(data, params \\ :invalid) do
data
|> cast(params, @required_fields ++ @optional_fields)
|> cast_attachments(params, @required_file_fields ++ @optional_file_fields)
|> validate_required(@required_fields)
|> validate_format(:email, ~r/@/)
|> unique_constraint(:email, message: "Email already taken")
|> validate_length(:password, min: 5)
|> validate_confirmation(:password, message: "Password does not match")
end
def image_changeset(data, params \\ :invalid) do
data
|> cast(params, @required_fields ++ @optional_fields)
|> cast_attachments(params, @required_file_fields ++ @optional_file_fields)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment