slightly changed how files are stored in the bucket and allows post deletion
This commit is contained in:
@@ -11,6 +11,10 @@ defmodule Mixer.Posts.Media do
|
||||
postgres do
|
||||
table "media"
|
||||
repo Mixer.Repo
|
||||
|
||||
references do
|
||||
reference :tweet, on_delete: :delete
|
||||
end
|
||||
end
|
||||
|
||||
typescript do
|
||||
|
||||
@@ -10,7 +10,7 @@ defmodule Mixer.Posts.MediaUploader do
|
||||
if ext in @extensions, do: :ok, else: {:error, "unsupported file type #{ext}"}
|
||||
end
|
||||
|
||||
def storage_dir(_version, {_file, scope}), do: "uploads/media/#{scope.id}"
|
||||
def storage_dir(_version, {_file, scope}), do: "uploads/media/#{scope.user_id}/#{scope.media_id}"
|
||||
|
||||
def filename(_version, {file, _scope}) do
|
||||
Path.basename(file.file_name, Path.extname(file.file_name))
|
||||
|
||||
@@ -8,6 +8,10 @@ defmodule Mixer.Posts.TweetLike do
|
||||
postgres do
|
||||
table "tweet_likes"
|
||||
repo Mixer.Repo
|
||||
|
||||
references do
|
||||
reference :tweet, on_delete: :delete
|
||||
end
|
||||
end
|
||||
|
||||
actions do
|
||||
|
||||
@@ -11,15 +11,17 @@ defmodule MixerWeb.UploadController do
|
||||
|> put_status(:unauthorized)
|
||||
|> json(%{error: "authentication required"})
|
||||
else
|
||||
scope = %{id: Ash.UUID.generate()}
|
||||
media_id = Ash.UUID.generate()
|
||||
scope = %{user_id: actor.id, media_id: media_id}
|
||||
|
||||
case MediaUploader.store({upload, scope}) do
|
||||
{:ok, file_name} ->
|
||||
s3_key = "uploads/media/#{scope.id}/#{file_name}"
|
||||
s3_key = "uploads/media/#{scope.user_id}/#{scope.media_id}/#{file_name}"
|
||||
url = MediaUploader.url({file_name, scope})
|
||||
|
||||
Mixer.Posts.Media
|
||||
|> Ash.Changeset.for_create(:upload, %{s3_key: s3_key}, actor: actor)
|
||||
|> Ash.Changeset.force_change_attribute(:id, media_id)
|
||||
|> Ash.create()
|
||||
|> case do
|
||||
{:ok, media} ->
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
defmodule Mixer.Repo.Migrations.CascadeDeleteTweetRelations do
|
||||
@moduledoc """
|
||||
Updates resources based on their most recent snapshots.
|
||||
|
||||
This file was autogenerated with `mix ash_postgres.generate_migrations`
|
||||
"""
|
||||
|
||||
use Ecto.Migration
|
||||
|
||||
def up do
|
||||
drop constraint(:tweet_likes, "tweet_likes_tweet_id_fkey")
|
||||
|
||||
alter table(:tweet_likes) do
|
||||
modify :tweet_id,
|
||||
references(:tweets,
|
||||
column: :id,
|
||||
name: "tweet_likes_tweet_id_fkey",
|
||||
type: :uuid,
|
||||
prefix: "public",
|
||||
on_delete: :delete_all
|
||||
)
|
||||
end
|
||||
|
||||
drop constraint(:media, "media_tweet_id_fkey")
|
||||
|
||||
alter table(:media) do
|
||||
modify :tweet_id,
|
||||
references(:tweets,
|
||||
column: :id,
|
||||
name: "media_tweet_id_fkey",
|
||||
type: :uuid,
|
||||
prefix: "public",
|
||||
on_delete: :delete_all
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def down do
|
||||
drop constraint(:media, "media_tweet_id_fkey")
|
||||
|
||||
alter table(:media) do
|
||||
modify :tweet_id,
|
||||
references(:tweets,
|
||||
column: :id,
|
||||
name: "media_tweet_id_fkey",
|
||||
type: :uuid,
|
||||
prefix: "public"
|
||||
)
|
||||
end
|
||||
|
||||
drop constraint(:tweet_likes, "tweet_likes_tweet_id_fkey")
|
||||
|
||||
alter table(:tweet_likes) do
|
||||
modify :tweet_id,
|
||||
references(:tweets,
|
||||
column: :id,
|
||||
name: "tweet_likes_tweet_id_fkey",
|
||||
type: :uuid,
|
||||
prefix: "public"
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
106
priv/resource_snapshots/repo/media/20260331210905.json
Normal file
106
priv/resource_snapshots/repo/media/20260331210905.json
Normal file
@@ -0,0 +1,106 @@
|
||||
{
|
||||
"attributes": [
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "fragment(\"gen_random_uuid()\")",
|
||||
"generated?": false,
|
||||
"precision": null,
|
||||
"primary_key?": true,
|
||||
"references": null,
|
||||
"scale": null,
|
||||
"size": null,
|
||||
"source": "id",
|
||||
"type": "uuid"
|
||||
},
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"precision": null,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"scale": null,
|
||||
"size": null,
|
||||
"source": "s3_key",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"precision": null,
|
||||
"primary_key?": false,
|
||||
"references": {
|
||||
"deferrable": false,
|
||||
"destination_attribute": "id",
|
||||
"destination_attribute_default": null,
|
||||
"destination_attribute_generated": null,
|
||||
"index?": false,
|
||||
"match_type": null,
|
||||
"match_with": null,
|
||||
"multitenancy": {
|
||||
"attribute": null,
|
||||
"global": null,
|
||||
"strategy": null
|
||||
},
|
||||
"name": "media_user_id_fkey",
|
||||
"on_delete": null,
|
||||
"on_update": null,
|
||||
"primary_key?": true,
|
||||
"schema": "public",
|
||||
"table": "users"
|
||||
},
|
||||
"scale": null,
|
||||
"size": null,
|
||||
"source": "user_id",
|
||||
"type": "uuid"
|
||||
},
|
||||
{
|
||||
"allow_nil?": true,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"precision": null,
|
||||
"primary_key?": false,
|
||||
"references": {
|
||||
"deferrable": false,
|
||||
"destination_attribute": "id",
|
||||
"destination_attribute_default": null,
|
||||
"destination_attribute_generated": null,
|
||||
"index?": false,
|
||||
"match_type": null,
|
||||
"match_with": null,
|
||||
"multitenancy": {
|
||||
"attribute": null,
|
||||
"global": null,
|
||||
"strategy": null
|
||||
},
|
||||
"name": "media_tweet_id_fkey",
|
||||
"on_delete": "delete",
|
||||
"on_update": null,
|
||||
"primary_key?": true,
|
||||
"schema": "public",
|
||||
"table": "tweets"
|
||||
},
|
||||
"scale": null,
|
||||
"size": null,
|
||||
"source": "tweet_id",
|
||||
"type": "uuid"
|
||||
}
|
||||
],
|
||||
"base_filter": null,
|
||||
"check_constraints": [],
|
||||
"create_table_options": null,
|
||||
"custom_indexes": [],
|
||||
"custom_statements": [],
|
||||
"has_create_action": true,
|
||||
"hash": "B9772141860212686745F81D509EBD97BACB9A5A4E7C26A0EB924D6926D1827E",
|
||||
"identities": [],
|
||||
"multitenancy": {
|
||||
"attribute": null,
|
||||
"global": null,
|
||||
"strategy": null
|
||||
},
|
||||
"repo": "Elixir.Mixer.Repo",
|
||||
"schema": null,
|
||||
"table": "media"
|
||||
}
|
||||
113
priv/resource_snapshots/repo/tweet_likes/20260331210906.json
Normal file
113
priv/resource_snapshots/repo/tweet_likes/20260331210906.json
Normal file
@@ -0,0 +1,113 @@
|
||||
{
|
||||
"attributes": [
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "fragment(\"gen_random_uuid()\")",
|
||||
"generated?": false,
|
||||
"precision": null,
|
||||
"primary_key?": true,
|
||||
"references": null,
|
||||
"scale": null,
|
||||
"size": null,
|
||||
"source": "id",
|
||||
"type": "uuid"
|
||||
},
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"precision": null,
|
||||
"primary_key?": false,
|
||||
"references": {
|
||||
"deferrable": false,
|
||||
"destination_attribute": "id",
|
||||
"destination_attribute_default": null,
|
||||
"destination_attribute_generated": null,
|
||||
"index?": false,
|
||||
"match_type": null,
|
||||
"match_with": null,
|
||||
"multitenancy": {
|
||||
"attribute": null,
|
||||
"global": null,
|
||||
"strategy": null
|
||||
},
|
||||
"name": "tweet_likes_tweet_id_fkey",
|
||||
"on_delete": "delete",
|
||||
"on_update": null,
|
||||
"primary_key?": true,
|
||||
"schema": "public",
|
||||
"table": "tweets"
|
||||
},
|
||||
"scale": null,
|
||||
"size": null,
|
||||
"source": "tweet_id",
|
||||
"type": "uuid"
|
||||
},
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"precision": null,
|
||||
"primary_key?": false,
|
||||
"references": {
|
||||
"deferrable": false,
|
||||
"destination_attribute": "id",
|
||||
"destination_attribute_default": null,
|
||||
"destination_attribute_generated": null,
|
||||
"index?": false,
|
||||
"match_type": null,
|
||||
"match_with": null,
|
||||
"multitenancy": {
|
||||
"attribute": null,
|
||||
"global": null,
|
||||
"strategy": null
|
||||
},
|
||||
"name": "tweet_likes_user_id_fkey",
|
||||
"on_delete": null,
|
||||
"on_update": null,
|
||||
"primary_key?": true,
|
||||
"schema": "public",
|
||||
"table": "users"
|
||||
},
|
||||
"scale": null,
|
||||
"size": null,
|
||||
"source": "user_id",
|
||||
"type": "uuid"
|
||||
}
|
||||
],
|
||||
"base_filter": null,
|
||||
"check_constraints": [],
|
||||
"create_table_options": null,
|
||||
"custom_indexes": [],
|
||||
"custom_statements": [],
|
||||
"has_create_action": true,
|
||||
"hash": "A5479A2259477E7040C393810B5805794903152376377FA38E92C119C4947108",
|
||||
"identities": [
|
||||
{
|
||||
"all_tenants?": false,
|
||||
"base_filter": null,
|
||||
"index_name": "tweet_likes_unique_user_tweet_index",
|
||||
"keys": [
|
||||
{
|
||||
"type": "atom",
|
||||
"value": "tweet_id"
|
||||
},
|
||||
{
|
||||
"type": "atom",
|
||||
"value": "user_id"
|
||||
}
|
||||
],
|
||||
"name": "unique_user_tweet",
|
||||
"nils_distinct?": true,
|
||||
"where": null
|
||||
}
|
||||
],
|
||||
"multitenancy": {
|
||||
"attribute": null,
|
||||
"global": null,
|
||||
"strategy": null
|
||||
},
|
||||
"repo": "Elixir.Mixer.Repo",
|
||||
"schema": null,
|
||||
"table": "tweet_likes"
|
||||
}
|
||||
Reference in New Issue
Block a user