← スキル一覧に戻る

active-interaction-coder
by majesticlabs-dev
⭐ 18🍴 1📅 2026年1月24日
SKILL.md
name: active-interaction-coder description: Implement typed business operations with ActiveInteraction. Covers input types, composition, controller patterns, and testing.
ActiveInteraction Coder
Typed business operations as the structured alternative to service objects.
Why ActiveInteraction Over Service Objects
| Service Objects | ActiveInteraction |
|---|---|
| No standard interface | Consistent .run / .run! |
| Manual type checking | Built-in type declarations |
| Manual validation | Standard Rails validations |
| Hard to compose | Native composition |
| Verbose boilerplate | Clean, self-documenting |
Setup
# Gemfile
gem "active_interaction", "~> 5.3"
Simple Interaction
# app/interactions/users/create.rb
module Users
class Create < ActiveInteraction::Base
# Typed inputs
string :email
string :name
string :password, default: nil
# Validations
validates :email, presence: true, format: { with: URI::MailTo::EMAIL_REGEXP }
validates :name, presence: true
# Main logic
def execute
user = User.create!(
email: email,
name: name,
password: password || SecureRandom.alphanumeric(32)
)
UserMailer.welcome(user).deliver_later
user # Return value becomes outcome.result
end
end
end
Running Interactions
# In controller
def create
outcome = Users::Create.run(
email: params[:email],
name: params[:name]
)
if outcome.valid?
redirect_to outcome.result, notice: "User created"
else
@errors = outcome.errors
render :new, status: :unprocessable_entity
end
end
# With bang method (raises on error)
user = Users::Create.run!(email: "user@example.com", name: "John")
Input Types
class MyInteraction < ActiveInteraction::Base
# Primitives
string :name
integer :age
float :price
boolean :active
symbol :status
# Date/Time
date :birthday
time :created_at
date_time :scheduled_at
# Complex types
array :tags
hash :metadata
# Model instances
object :user, class: User
# Typed arrays
array :emails, default: [] do
string
end
# Optional with default
string :optional_field, default: nil
integer :count, default: 0
end
Composing Interactions
module Users
class Register < ActiveInteraction::Base
string :email, :name, :password
def execute
# Compose calls another interaction
user = compose(Users::Create,
email: email,
name: name,
password: password
)
# Errors automatically merged if nested fails
compose(Users::SendWelcomeEmail, user: user)
user
end
end
end
Controller Pattern
class ArticlesController < ApplicationController
def create
outcome = Articles::Create.run(
title: params[:article][:title],
body: params[:article][:body],
author: current_user
)
if outcome.valid?
redirect_to article_path(outcome.result), notice: "Article created"
else
@article = Article.new(article_params)
@article.errors.merge!(outcome.errors)
render :new, status: :unprocessable_entity
end
end
end
Testing Interactions
RSpec.describe Users::Create do
let(:valid_params) { { email: "user@example.com", name: "John" } }
it "creates user with valid inputs" do
expect { described_class.run(valid_params) }
.to change(User, :count).by(1)
end
it "returns valid outcome" do
outcome = described_class.run(valid_params)
expect(outcome).to be_valid
expect(outcome.result).to be_a(User)
end
it "validates email format" do
outcome = described_class.run(valid_params.merge(email: "invalid"))
expect(outcome).not_to be_valid
expect(outcome.errors[:email]).to be_present
end
end
Advanced Patterns
For composition, error handling, and custom types see:
references/active-interaction.md
スコア
総合スコア
60/100
リポジトリの品質指標に基づく評価
✓SKILL.md
SKILL.mdファイルが含まれている
+20
✓LICENSE
ライセンスが設定されている
+10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
○最近の活動
3ヶ月以内に更新がある
0/10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
○タグ
1つ以上のタグが設定されている
0/5
レビュー
💬
レビュー機能は近日公開予定です