Packages

phoenix_kit

1.7.21
1.7.208 1.7.207 1.7.206 1.7.205 1.7.204 1.7.203 1.7.202 1.7.201 1.7.200 1.7.199 1.7.198 1.7.197 1.7.196 1.7.194 1.7.193 1.7.192 1.7.191 1.7.190 1.7.189 1.7.187 1.7.186 1.7.185 1.7.184 1.7.183 1.7.182 1.7.181 1.7.180 1.7.179 1.7.178 1.7.177 1.7.176 1.7.175 1.7.174 1.7.173 1.7.172 1.7.171 1.7.170 1.7.169 1.7.168 1.7.167 1.7.166 1.7.165 1.7.164 1.7.162 1.7.161 1.7.160 1.7.159 1.7.157 1.7.156 1.7.155 1.7.154 1.7.153 1.7.152 1.7.151 1.7.150 1.7.149 1.7.146 1.7.145 1.7.144 1.7.143 1.7.138 1.7.133 1.7.132 1.7.131 1.7.130 1.7.128 1.7.126 1.7.125 1.7.121 1.7.120 1.7.119 1.7.118 1.7.117 1.7.116 1.7.115 1.7.114 1.7.113 1.7.112 1.7.111 1.7.110 1.7.109 1.7.108 1.7.107 1.7.106 1.7.105 1.7.104 1.7.103 1.7.102 1.7.101 1.7.100 1.7.99 1.7.98 1.7.97 1.7.96 1.7.95 1.7.94 1.7.93 1.7.92 1.7.91 1.7.90 1.7.89 1.7.88 1.7.87 1.7.86 1.7.85 1.7.84 1.7.83 1.7.82 1.7.81 1.7.80 1.7.79 1.7.78 1.7.77 1.7.76 1.7.75 1.7.74 1.7.71 1.7.70 1.7.69 1.7.66 1.7.65 1.7.64 1.7.63 1.7.62 1.7.61 1.7.59 1.7.58 1.7.57 1.7.56 1.7.55 1.7.54 1.7.53 1.7.52 1.7.51 1.7.49 1.7.44 1.7.43 1.7.42 1.7.41 1.7.39 1.7.38 1.7.37 1.7.36 1.7.34 1.7.33 1.7.31 1.7.30 1.7.29 1.7.28 1.7.27 1.7.26 1.7.25 1.7.24 1.7.23 1.7.22 1.7.21 1.7.20 1.7.19 1.7.18 1.7.17 1.7.16 1.7.15 1.7.14 1.7.13 1.7.12 1.7.11 1.7.10 1.7.9 1.7.8 1.7.7 1.7.6 1.7.5 1.7.4 1.7.3 1.7.2 1.7.1 1.7.0 1.6.20 1.6.19 1.6.18 1.6.17 1.6.16 1.6.15 1.6.14 1.6.13 1.6.12 1.6.11 1.6.10 1.6.9 1.6.8 1.6.7 1.6.6 1.6.5 1.6.4 1.6.3 1.5.2 1.5.1 1.5.0 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.2 1.3.1 1.3.0 1.2.10 1.2.9 1.2.8 1.2.7 1.2.5 1.2.4 1.2.2 1.2.1 1.2.0 1.1.0 1.0.0

A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more

Current section

Files

Jump to
phoenix_kit lib modules posts schemas post_media.ex
Raw

lib/modules/posts/schemas/post_media.ex

defmodule PhoenixKit.Modules.Posts.PostMedia do
@moduledoc """
Junction schema for post media attachments.
Links posts to uploaded files (images/videos) with ordering and captions.
Enables ordered image galleries in posts with per-image captions.
## Fields
- `post_id` - Reference to the post
- `file_id` - Reference to the uploaded file (PhoenixKit.Storage.File)
- `position` - Display order (1, 2, 3, etc.)
- `caption` - Optional caption/alt text for the image
## Examples
# First image in post
%PostMedia{
post_id: "018e3c4a-9f6b-7890-abcd-ef1234567890",
file_id: "018e3c4a-1234-5678-abcd-ef1234567890",
position: 1,
caption: "Beautiful sunset at the beach"
}
# Second image
%PostMedia{
post_id: "018e3c4a-9f6b-7890-abcd-ef1234567890",
file_id: "018e3c4a-5678-1234-abcd-ef1234567890",
position: 2,
caption: nil
}
"""
use Ecto.Schema
import Ecto.Changeset
@primary_key {:id, UUIDv7, autogenerate: true}
@foreign_key_type UUIDv7
@type t :: %__MODULE__{
id: UUIDv7.t() | nil,
post_id: UUIDv7.t(),
file_id: UUIDv7.t(),
position: integer(),
caption: String.t() | nil,
post: PhoenixKit.Modules.Posts.Post.t() | Ecto.Association.NotLoaded.t(),
file: PhoenixKit.Modules.Storage.File.t() | Ecto.Association.NotLoaded.t(),
inserted_at: NaiveDateTime.t() | nil,
updated_at: NaiveDateTime.t() | nil
}
schema "phoenix_kit_post_media" do
field :position, :integer
field :caption, :string
belongs_to :post, PhoenixKit.Modules.Posts.Post
belongs_to :file, PhoenixKit.Modules.Storage.File
timestamps(type: :naive_datetime)
end
@doc """
Changeset for creating or updating post media.
## Required Fields
- `post_id` - Reference to post
- `file_id` - Reference to file
- `position` - Display order (must be positive)
## Validation Rules
- Position must be greater than 0
- Unique constraint on (post_id, position) - enforced at database level
"""
def changeset(media, attrs) do
media
|> cast(attrs, [:post_id, :file_id, :position, :caption])
|> validate_required([:post_id, :file_id, :position])
|> validate_number(:position, greater_than: 0)
|> foreign_key_constraint(:post_id)
|> foreign_key_constraint(:file_id)
|> unique_constraint([:post_id, :position],
name: :phoenix_kit_post_media_post_id_position_index,
message: "position already taken for this post"
)
end
end