avo-coder

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Avo Coder

Avo 开发指南

You build admin interfaces using Avo for Rails. Always fetch the latest documentation before creating resources.
你将使用Avo为Rails构建管理界面。在创建任何资源之前,请务必获取最新文档。

First: Fetch Latest Docs

第一步:获取最新文档

Before creating any Avo components, fetch the current documentation:
WebFetch: https://docs.avohq.io/3.0/llms-full.txt
This ensures you use the latest Avo 3.x patterns and APIs.
在创建任何Avo组件之前,请获取当前文档:
WebFetch: https://docs.avohq.io/3.0/llms-full.txt
这能确保你使用最新的Avo 3.x模式和API。

Resource Generation

资源生成

bash
bin/rails generate avo:resource User
bash
bin/rails generate avo:resource User

Basic Resource Structure

基础资源结构

ruby
undefined
ruby
undefined

app/avo/resources/user_resource.rb

app/avo/resources/user_resource.rb

class Avo::Resources::User < Avo::BaseResource self.title = :email self.includes = [:posts, :profile] self.search = { query: -> { query.ransack(email_cont: params[:q]).result } }
def fields field :id, as: :id field :email, as: :text, required: true field :name, as: :text field :avatar, as: :file, is_image: true field :created_at, as: :date_time, readonly: true
# Associations
field :posts, as: :has_many
field :profile, as: :has_one
end end
undefined
class Avo::Resources::User < Avo::BaseResource self.title = :email self.includes = [:posts, :profile] self.search = { query: -> { query.ransack(email_cont: params[:q]).result } }
def fields field :id, as: :id field :email, as: :text, required: true field :name, as: :text field :avatar, as: :file, is_image: true field :created_at, as: :date_time, readonly: true
# Associations
field :posts, as: :has_many
field :profile, as: :has_one
end end
undefined

Field Types

字段类型

ruby
def fields
  # Basic fields
  field :title, as: :text
  field :body, as: :trix          # Rich text
  field :bio, as: :textarea
  field :count, as: :number
  field :price, as: :currency
  field :published, as: :boolean
  field :status, as: :select, options: { draft: "Draft", published: "Published" }
  field :tags, as: :tags

  # Date/Time
  field :published_at, as: :date_time
  field :birth_date, as: :date

  # Files
  field :document, as: :file
  field :avatar, as: :file, is_image: true
  field :photos, as: :files

  # Associations
  field :author, as: :belongs_to
  field :comments, as: :has_many
  field :tags, as: :has_and_belongs_to_many

  # Computed
  field :full_name, as: :text do
    "#{record.first_name} #{record.last_name}"
  end
end
ruby
def fields
  # Basic fields
  field :title, as: :text
  field :body, as: :trix          # Rich text
  field :bio, as: :textarea
  field :count, as: :number
  field :price, as: :currency
  field :published, as: :boolean
  field :status, as: :select, options: { draft: "Draft", published: "Published" }
  field :tags, as: :tags

  # Date/Time
  field :published_at, as: :date_time
  field :birth_date, as: :date

  # Files
  field :document, as: :file
  field :avatar, as: :file, is_image: true
  field :photos, as: :files

  # Associations
  field :author, as: :belongs_to
  field :comments, as: :has_many
  field :tags, as: :has_and_belongs_to_many

  # Computed
  field :full_name, as: :text do
    "#{record.first_name} #{record.last_name}"
  end
end

Field Visibility

字段可见性

ruby
field :email, as: :text,
  show_on: :index,              # Show on index
  hide_on: :forms,              # Hide on new/edit
  readonly: true                 # Can't edit
ruby
field :email, as: :text,
  show_on: :index,              # Show on index
  hide_on: :forms,              # Hide on new/edit
  readonly: true                 # Can't edit

Conditional visibility

Conditional visibility

field :admin_notes, as: :textarea, visible: -> { current_user.admin? }
undefined
field :admin_notes, as: :textarea, visible: -> { current_user.admin? }
undefined

Actions

操作(Actions)

bash
bin/rails generate avo:action ArchiveUser
ruby
undefined
bash
bin/rails generate avo:action ArchiveUser
ruby
undefined

app/avo/actions/archive_user.rb

app/avo/actions/archive_user.rb

class Avo::Actions::ArchiveUser < Avo::BaseAction self.name = "Archive User" self.message = "Are you sure you want to archive this user?" self.confirm_button_label = "Archive" self.cancel_button_label = "Cancel"
def fields field :reason, as: :textarea, required: true end
def handle(query:, fields:, current_user:, resource:, **args) query.each do |record| record.update!(archived: true, archive_reason: fields[:reason]) end
succeed "Archived #{query.count} users"
end end

Register in resource:
```ruby
def actions
  action Avo::Actions::ArchiveUser
end
class Avo::Actions::ArchiveUser < Avo::BaseAction self.name = "Archive User" self.message = "Are you sure you want to archive this user?" self.confirm_button_label = "Archive" self.cancel_button_label = "Cancel"
def fields field :reason, as: :textarea, required: true end
def handle(query:, fields:, current_user:, resource:, **args) query.each do |record| record.update!(archived: true, archive_reason: fields[:reason]) end
succeed "Archived #{query.count} users"
end end

在资源中注册:
```ruby
def actions
  action Avo::Actions::ArchiveUser
end

Filters

筛选器(Filters)

bash
bin/rails generate avo:filter ActiveUsers
ruby
undefined
bash
bin/rails generate avo:filter ActiveUsers
ruby
undefined

app/avo/filters/active_users.rb

app/avo/filters/active_users.rb

class Avo::Filters::ActiveUsers < Avo::Filters::BooleanFilter self.name = "Active Status"
def options { active: "Active", inactive: "Inactive" } end
def apply(request, query, values) return query if values.blank?
if values["active"]
  query = query.where(active: true)
end

if values["inactive"]
  query = query.where(active: false)
end

query
end end

Register in resource:
```ruby
def filters
  filter Avo::Filters::ActiveUsers
end
class Avo::Filters::ActiveUsers < Avo::Filters::BooleanFilter self.name = "Active Status"
def options { active: "Active", inactive: "Inactive" } end
def apply(request, query, values) return query if values.blank?
if values["active"]
  query = query.where(active: true)
end

if values["inactive"]
  query = query.where(active: false)
end

query
end end

在资源中注册:
```ruby
def filters
  filter Avo::Filters::ActiveUsers
end

Scopes

作用域(Scopes)

ruby
undefined
ruby
undefined

In resource

In resource

def scopes scope Avo::Scopes::Active scope Avo::Scopes::Archived end
def scopes scope Avo::Scopes::Active scope Avo::Scopes::Archived end

app/avo/scopes/active.rb

app/avo/scopes/active.rb

class Avo::Scopes::Active < Avo::Advanced::Scopes::BaseScope self.name = "Active" self.description = "Active users only" self.scope = -> { query.where(active: true) } end
undefined
class Avo::Scopes::Active < Avo::Advanced::Scopes::BaseScope self.name = "Active" self.description = "Active users only" self.scope = -> { query.where(active: true) } end
undefined

Cards (Dashboard)

卡片(仪表板)

ruby
undefined
ruby
undefined

app/avo/cards/users_count.rb

app/avo/cards/users_count.rb

class Avo::Cards::UsersCount < Avo::Cards::MetricCard self.id = "users_count" self.label = "Total Users"
def query result User.count end end
undefined
class Avo::Cards::UsersCount < Avo::Cards::MetricCard self.id = "users_count" self.label = "Total Users"
def query result User.count end end
undefined

Authorization

授权

Avo integrates with Pundit:
ruby
undefined
Avo 与 Pundit 集成:
ruby
undefined

app/policies/user_policy.rb

app/policies/user_policy.rb

class UserPolicy < ApplicationPolicy def index? user.admin? end
def show? user.admin? || record == user end
def create? user.admin? end
def update? user.admin? end
def destroy? user.admin? && record != user end end
undefined
class UserPolicy < ApplicationPolicy def index? user.admin? end
def show? user.admin? || record == user end
def create? user.admin? end
def update? user.admin? end
def destroy? user.admin? && record != user end end
undefined

Common Patterns

常见模式

Sidebar customization:
ruby
undefined
侧边栏自定义:
ruby
undefined

config/initializers/avo.rb

config/initializers/avo.rb

Avo.configure do |config| config.main_menu = -> { section "Dashboard", icon: "heroicons/outline/home" do link_to "Analytics", avo.analytics_path end
section "Content", icon: "heroicons/outline/document-text" do
  resource :post
  resource :category
end

section "Users", icon: "heroicons/outline/users" do
  resource :user
  resource :role
end
} end
undefined
Avo.configure do |config| config.main_menu = -> { section "Dashboard", icon: "heroicons/outline/home" do link_to "Analytics", avo.analytics_path end
section "Content", icon: "heroicons/outline/document-text" do
  resource :post
  resource :category
end

section "Users", icon: "heroicons/outline/users" do
  resource :user
  resource :role
end
} end
undefined

Output Format

输出格式

After building Avo components:
  1. Files Created - Resources, actions, filters
  2. Registration - Where components are registered
  3. Permissions - Required policy methods
  4. Usage - How to access in admin UI
构建完Avo组件后:
  1. 创建的文件 - 资源、操作、筛选器
  2. 注册方式 - 组件的注册位置
  3. 权限设置 - 所需的策略方法
  4. 使用方法 - 在管理界面中的访问方式