跳到主要内容
知仓学习社ZHICANG

ash-framework

Ash Framework — resources, actions, policies, aggregates, calculations,

不碰外部(只输出文字)无严重或高危命中oliver-kriska/claude-elixir-phoenix

它会碰到什么

扫了多少1 个文本文件,5 KB
它会碰到什么不碰外部(只输出文字)
命中总数0 处
命中统计严重 0 · 高 0 · 中 0 · 低 0

这一栏是扫描器报的事实,不是结论。命中多不等于有毒(安全工具、规则库、示例脚本本来就会包含危险写法),命中少也不等于干净。它和你手上的凭据、文件、网络有什么关系,需要你自己看。

技能内容

Ash Framework Reference

Reference for Ash Framework in Phoenix/LiveView projects.

Ash complements Phoenix/Ecto — LiveView, security, and OTP Iron Laws still apply.

Only data access patterns shift toward Ash actions and domain code interfaces.

Iron Laws

  1. USE DOMAIN CODE INTERFACES — Never call Ash.create/Ash.read directly in LiveViews or Controllers; use domain code interfaces: MyApp.Accounts.register_user() not Ash.create(User, attrs)
  2. SET ACTOR/SCOPE AT QUERY PREP, NOT EXECUTION — Pass actor: or scope: to

for_read/for_create/for_action (prep), NOT to Ash.read!/Ash.create! (execution);

execution-level actor bypasses row-level policy evaluation. If project uses Ash.Scope,

pass scope: consistently instead of bare actor: — do not mix styles

  1. GENERATORS FIRST — Before writing Ash code manually, run mix ash.gen.resource or mix ash.gen.domain with --yes; check mix help ash.gen.<task> for options
  2. CODEGEN AFTER RESOURCE CHANGES — Always run mix ash.codegen after modifying resources; this generates migrations from resource snapshots — never write AshPostgres migrations by hand
  3. ACTIONS OVER FUNCTIONS — Put business logic in named actions, not domain functions; expose via code interfaces defined on the domain
  4. NEVER EDIT RESOURCE SNAPSHOTSpriv/resource_snapshots/ is owned exclusively by mix ash.codegen; manual edits corrupt migration tracking
  5. **NO DIRECT Repo. IN ASH PROJECTS* — Repo.all/get/insert bypass Ash policies and notifications; use domain code interfaces. Any Repo call in an Ash project is an escape hatch and must be documented

Quick Reference

Domain Code Interface Pattern

# Domain definition
defmodule MyApp.Accounts do
  use Ash.Domain

  resources do
    resource MyApp.Accounts.User do
      define :register_user, action: :create, args: [:email, :password]
      define :get_user_by_email, action: :read, get_by: [:email]
    end
  end
end

# In LiveView/Controller — always via domain, never Ash.create directly
{:ok, user} = MyApp.Accounts.register_user(email, password, actor: nil)
user = MyApp.Accounts.get_user_by_email!(email, actor: current_user)

Authorization — Actor/Scope at Query Prep

# CORRECT — actor at query prep, policies evaluated per-row
MyApp.Post
|> Ash.Query.for_read(:list_published, %{}, actor: current_user)
|> Ash.read!()

# CORRECT with Ash.Scope (carries actor + tenant + context; use if project adopts it)
MyApp.Post
|> Ash.Query.for_read(:list_published, %{}, scope: scope)
|> Ash.read!()

# WRONG — actor at execution bypasses row-level policy evaluation
MyApp.Post
|> Ash.Query.for_read(:list_published)
|> Ash.read!(actor: current_user)

Ash.Scope — When the Project Uses It

Ash.Scope bundles actor + tenant + context into a single struct passed through actions.

Implement Ash.Scope.ToOpts on a project-defined scope struct:

defimpl Ash.Scope.ToOpts, for: MyApp.Scope do
  def get_actor(%{current_user: u}), do: {:ok, u}
  def get_tenant(%{current_tenant: t}), do: {:ok, t}
  def get_context(%{locale: l}), do: {:ok, %{shared: %{locale: l}}}
  def get_tracer(_), do: :error
  def get_authorize?(_), do: :error
end

Detection: if the project has a Scope module implementing Ash.Scope.ToOpts, use

scope: everywhere instead of bare actor:. Do NOT mix the two styles in the same codebase.

See mix usage_rules.docs Ash.Scope for full protocol spec.

File Conventions (from mix ash.gen.*)

| File | Location | Behaviour |

| -------------- | --------------------------------- | ----------------------------- |

| Changes | lib/app/ctx/changes/name.ex | use Ash.Resource.Change |

| Policy Checks | lib/app/ctx/checks/name.ex | use Ash.Policy.Check |

| Custom Actions | lib/app/ctx/actions/name.ex | generic action logic |

| Custom Types | lib/app/ctx/types/name.ex | use Ash.Type |

| Validations | lib/app/ctx/validations/name.ex | use Ash.Resource.Validation |

Generator Workflow

mix ash.gen.resource MyApp.Accounts.User --yes
mix ash.gen.domain MyApp.Accounts --yes
mix ash.codegen        # reads resource snapshots → generates migration
mix ash.migrate

Research

Prefer the highest-fidelity source available:

  1. Tidewave (exact version from mix.lock):
   mcp__tidewave__get_docs(module: "Ash.Resource")
   mcp__tidewave__get_docs(module: "AshPhoenix.Form")
  1. usage_rules (project-synced to your installed ash_* dep versions):
   mix usage_rules.search_docs "<topic>" -p ash -p ash_phoenix -p ash_postgres -p ash_authentication -p ash_oban
   mix usage_rules.docs Ash.Resource
  1. WebFetch hexdocs.pm (fallback when neither is available):
   WebFetch(url: "https://hexdocs.pm/ash/Ash.Resource.html", prompt: "Extract module docs.")

If usage_rules is not configured, the SessionStart hook suggests how to install it.

想直接用这个技能?

本站把开放许可(MIT / Apache 等)的技能按仓库打包整理到网盘,点一下转存到你自己的网盘,不用一个个从 GitHub 拉。许可未声明的技能只给原始仓库链接,不打包。

它属于哪个仓库

星标★ 553
本站分层T2
该仓技能数322
原文件路径targets/pi/skills/ash-framework/SKILL.md

同一个仓库里的其他技能

看这个仓库的全部 322 个技能

同名技能的其他版本

有 6 个不同仓库或目录里都有叫 ash-framework 的技能。它们内容并不相同,别混用: