Links

Elixir Phoenix

Learn how to configure an Elixir Phoenix App for use with Filebase.

What is Elixir Phoenix?

Elixir Phoenix is a web framework built using the Elixir programming language. It is designed to help developers quickly build scalable and fault-tolerant web applications that can handle large amounts of traffic. Phoenix provides many features that are common to modern web frameworks, including a request/response cycle, a routing system, controllers, views, and templates. It is a popular choice for building real-time applications, such as chat apps, games, and social media platforms, as well as traditional web applications.
Read below to learn how to use Elixir Phoenix with Filebase.

Prerequisites:

1. Create a new Elixir project with the command:

mix phx.new file_upload_app
cd file_upload_app

2. Next, create a new database with the command:

mix ecto.create

3. Then, add the Ex.Aws.S3 package to your Elixir list of dependencies in your project’s mix.esc file:

{:ex_aws, "~> 2.0"},
{:ex_aws_s3, "~> 2.0"},
{:poison, "~> 3.0"},
{:hackney, "~> 1.9"},
{:sweet_xml, "~> 0.6.6"},

4. Install these dependencies with the command:

mix deps.get

5. Configure the Ex.Aws.S3 package to use your FIlebase instance with the following configuration in your project’s config/config.exs file:

config :ex_aws,
access_key_id: System.get_env("AWS_ACCESS_KEY_ID"),
secret_access_key: System.get_env("AWS_SECRET_ACCESS_KEY"),
s3: [
scheme: "https://",
host: "bucket-name.s3.filebase.com",
region: "us-east-1"
]
Replace ‘bucket-name’ with your Filebase bucket name.

6. Create a .env file with the following environment variables:

export AWS_ACCESS_KEY_ID=FILEBASE_ACCESS_KEY
export AWS_SECRET_ACCESS_KEY=FILEBASE_SECRET_KEY

7. Then, source this environmental variable file with the command:

source .env

8. Next, in the lib/file_upload_app_web/router.ex file, add the following code:

scope “/, FileUploadAppWeb do
pipe_through :browser
resources “/upload”, UploadController, only: [:create, :new]
end

9. Create a new migration with the command:

mix ecto.gen.migration add_uploads

10. This command will create a new file located at priv/repo/migrations/add_uploads.exs. Open this file and insert the following code:

defmodule FileUploadApp.Repo.Migrations.AddUploads do
use Ecto.Migration
def change do
create table(:uploads) do
add :image_url, :string
timestamps()
end
end
end

11. Then apply the changes to the Elixir project with the command:

mix ecto.migrate

12. Within the file_upload_app_web folder, create a new folder called models, with a new file inside called upload.ex. Insert the following code:

defmodule FileUploadApp.Upload do
use FileUploadApp.Web, :model
schema "uploads" do
field :image_url, :string
timestamps()
end
def changeset(struct, params \\\\ :invalid) do
struct
|> cast(params, [:image_url])
|> validate_required([:image_url])
end
end

13. Next, within the templates folder, create a new folder called upload, then within that folder create a new file called new.html.eex. Inside this new file, insert the following:

<%= form_for @changeset, upload_path(@conn, :create), [multipart: true] fn f -> %>
<div class="form-group">
<%= label f, :image, class: "control-label" %>
<%= file_input f, :image, class: "form-control" %>
<%= error_tag f, :image %>
</div>
<%= submit "Upload Image", class: "btn" %>
<% end %>

14. Lastly, create a new upload_controller.ex file in the controllers folder. Add the following code to the file:

defmodule FileUploadApp.UploadController do
use FileUploadApp.Web, :controller
alias FileUploadApp.Upload
def new(conn, _params) do
changeset = Upload.changeset(%Upload{})
render conn, "new.html", changeset: changeset
end
def create(conn, %{"upload" => %{"image" => image_params} = upload_params}) do
file_uuid = UUID.uuid4(:hex)
image_filename = image_params.filename
unique_filename = "#{file_uuid}-#{image_filename}"
{:ok, image_binary} = File.read(image_params.path)
bucket_name = System.get_env("BUCKET_NAME")
image =
ExAws.S3.put_object(bucket_name, unique_filename, image_binary)
|> ExAws.request!
updated_params =
upload_params
|> Map.update(image, image_params, fn _value -> "https://#{bucket_name}.s3.filebase.com/#{unique_filename}" end)
changeset = Upload.changeset(%Upload{}, updated_params)
case Repo.insert!(changeset) do
{:ok, upload} ->
conn
|> put_flash(:info, "Image uploaded successfully!")
|> redirect(to: upload_path(conn, :new))
{:error, changeset} ->
render conn, "new.html", changeset: changeset
end
end
end

15. Now it’s time to start the server. Use the command:

mix phoenix.server

16. The server will start on localhost:4000. Open this in a web browser, then go to localhost:4000/uploads/new to upload a file.

If you have any questions, please join our Discord server, or send us an email at [email protected]