Packages

phoenix_kit

1.7.33
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 connections block.ex
Raw

lib/modules/connections/block.ex

defmodule PhoenixKit.Modules.Connections.Block do
@moduledoc """
Schema for user blocking relationships.
Represents a one-way block where one user blocks another.
Blocking prevents all interaction between users.
## Fields
- `blocker_id` - User who initiated the block
- `blocked_id` - User who is blocked
- `reason` - Optional reason for the block (visible to admins)
- `inserted_at` - When the block was created
## Examples
# User A blocks User B
%Block{
id: "018e3c4a-9f6b-7890-abcd-ef1234567890",
blocker_id: 1,
blocked_id: 2,
reason: "Spam",
inserted_at: ~N[2025-01-15 10:30:00]
}
## Business Rules
- Cannot block yourself
- Blocking removes any existing follows between the users
- Blocking removes any existing connections between the users
- Blocked users cannot follow, connect, or view the blocker's profile
- Blocking is one-way (A blocks B doesn't mean B blocks A)
"""
use Ecto.Schema
import Ecto.Changeset
@primary_key {:id, UUIDv7, autogenerate: true}
@type t :: %__MODULE__{
id: UUIDv7.t() | nil,
blocker_id: integer(),
blocked_id: integer(),
reason: String.t() | nil,
blocker: PhoenixKit.Users.Auth.User.t() | Ecto.Association.NotLoaded.t(),
blocked: PhoenixKit.Users.Auth.User.t() | Ecto.Association.NotLoaded.t(),
inserted_at: NaiveDateTime.t() | nil
}
schema "phoenix_kit_user_blocks" do
belongs_to :blocker, PhoenixKit.Users.Auth.User, type: :integer
belongs_to :blocked, PhoenixKit.Users.Auth.User, type: :integer
field :reason, :string
field :inserted_at, :naive_datetime
end
@doc """
Changeset for creating a block.
## Required Fields
- `blocker_id` - The user who is blocking
- `blocked_id` - The user being blocked
## Optional Fields
- `reason` - Why the user was blocked
## Validation Rules
- Both user IDs are required
- Cannot block yourself
- Unique constraint on (blocker_id, blocked_id) pair
"""
def changeset(block, attrs) do
block
|> cast(attrs, [:blocker_id, :blocked_id, :reason])
|> validate_required([:blocker_id, :blocked_id])
|> validate_length(:reason, max: 500)
|> validate_not_self_block()
|> put_inserted_at()
|> foreign_key_constraint(:blocker_id)
|> foreign_key_constraint(:blocked_id)
|> unique_constraint([:blocker_id, :blocked_id],
name: :phoenix_kit_user_blocks_unique_idx,
message: "user is already blocked"
)
end
defp validate_not_self_block(changeset) do
blocker_id = get_field(changeset, :blocker_id)
blocked_id = get_field(changeset, :blocked_id)
if blocker_id && blocked_id && blocker_id == blocked_id do
add_error(changeset, :blocked_id, "cannot block yourself")
else
changeset
end
end
defp put_inserted_at(changeset) do
if get_field(changeset, :inserted_at) do
changeset
else
put_change(
changeset,
:inserted_at,
NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second)
)
end
end
end