MishkaBlog.BloggerFollower (Mishka Blog v0.0.1)

Copy Markdown View Source

Manages user follows for bloggers.

This resource represents follow relationships where users can follow bloggers to stay updated with their content. Each follow links a user to a specific blogger and tracks when the follow occurred and notification preferences.

The unique constraint on follower_user_id and blogger_id ensures each user can only follow a specific blogger once. The notification_enabled field allows users to control whether they receive notifications about the blogger's new content.

This resource has no multitenancy of its own, so a follow may only name a blogger of the site it is made for — see MishkaCmsCore.Runtime.Resources.Validations.TenantIsolation — and :by_blogger lists only the followers of a blogger of the site it is asked on, and gives a site user nothing on any site but its own — see MishkaBlog.Resources.Preparations.SiteAskedOn. Database-level constraints ensure data integrity with cascade deletes when bloggers or users are removed.

Summary

Functions

Apply the full GuardedStruct pipeline (sanitize → validate → derive → main_validator) to attrs and return either {:ok, transformed_attrs} or {:error, errors}. Wire this into an Ash.Resource.Change to plug guardedstruct rules into Ash's changeset pipeline.

O(1) lookup of a field's compile-time metadata by name. Returns nil for unknown fields.

Compile-time-baked MapSet of every field name owned by the guardedstruct block. Used by GuardedStruct.AshResource.Change to decide, in O(1), whether a key in changeset.atomics belongs to the pipeline.

Validates that the keys in the provided input are valid for at least one action on the resource.

Same as input/1, except restricts the keys to values accepted by the action provided.

Types

t()

@type t() :: %MishkaBlog.BloggerFollower{
  __lateral_join_source__: term(),
  __meta__: term(),
  __metadata__: term(),
  __order__: term(),
  aggregates: term(),
  blogger: term(),
  blogger_id: term(),
  calculations: term(),
  followed_at: term(),
  follower_user: term(),
  follower_user_id: term(),
  id: term(),
  inserted_at: term(),
  notification_enabled: term(),
  updated_at: term()
}

Functions

__guarded_change__(attrs, error? \\ false)

Apply the full GuardedStruct pipeline (sanitize → validate → derive → main_validator) to attrs and return either {:ok, transformed_attrs} or {:error, errors}. Wire this into an Ash.Resource.Change to plug guardedstruct rules into Ash's changeset pipeline.

The function is named __guarded_change__ because it does more than validate — it can also transform values (trim, downcase, slugify, auto-fill, etc.) before they reach the data layer.

__guarded_field_meta__(name)

O(1) lookup of a field's compile-time metadata by name. Returns nil for unknown fields.

__guarded_field_name_set__()

Compile-time-baked MapSet of every field name owned by the guardedstruct block. Used by GuardedStruct.AshResource.Change to decide, in O(1), whether a key in changeset.atomics belongs to the pipeline.

default_short_name()

input(opts)

@spec input(values :: map() | Keyword.t()) :: map() | no_return()

Validates that the keys in the provided input are valid for at least one action on the resource.

Raises a KeyError error at compile time if not. This exists because generally a struct should only ever be created by Ash as a result of a successful action. You should not be creating records manually in code, e.g %MyResource{value: 1, value: 2}. Generally that is fine, but often with embedded resources it is nice to be able to validate the keys that are being provided, e.g

Resource
|> Ash.Changeset.for_create(:create, %{embedded: EmbeddedResource.input(foo: 1, bar: 2)})
|> Ash.create()

input(opts, action)

@spec input(values :: map() | Keyword.t(), action :: atom()) :: map() | no_return()

Same as input/1, except restricts the keys to values accepted by the action provided.

json_api_match_route(_, _)

primary_key_matches?(left, right)