Help us improve
Share bugs, ideas, or general feedback.
From rubyku
Concerns pattern for organizing business logic in models — the alternative to service classes following Rails Way standards
npx claudepluginhub ghozimahdi/gm-claude-plugins --plugin rubykuHow this skill is triggered — by the user, by Claude, or both
Slash command
/rubyku:concerns-patternThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This plugin enforces **concerns** to organize business logic, NEVER service classes.
Provides behavioral guidelines to reduce common LLM coding mistakes, focusing on simplicity, surgical changes, assumption surfacing, and verifiable success criteria.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Structures git workflow practices for committing, branching, resolving conflicts, and organizing work across parallel streams. Use when making any code change.
Share bugs, ideas, or general feedback.
This plugin enforces concerns to organize business logic, NEVER service classes.
| Type | Location | Module Name |
|---|---|---|
| Model-specific | app/models/model_name/concern.rb | ModelName::ConcernName |
| Shared across models | app/models/concerns/concern.rb | ConcernName |
| Controller | app/controllers/concerns/concern.rb | ConcernName |
# app/models/task/status_transitions.rb
module Task::StatusTransitions
extend ActiveSupport::Concern
included do
after_commit :notify_status_change, if: :saved_change_to_status?
scope :actionable, -> { where(status: [:pending, :in_progress]) }
end
def advance!
case status
when "pending" then update!(status: :in_progress)
when "in_progress" then update!(status: :completed)
end
end
def revert!
update!(status: :pending)
end
private
def notify_status_change
TaskMailer.status_changed(self).deliver_later
end
end
# app/models/task.rb
class Task < ApplicationRecord
include Task::StatusTransitions
include Task::Notifications
include Task::Validations
include AttributeLabels
acts_as_paranoid
belongs_to :user
has_many :ai_scheduled_events, as: :eventable
end
# app/models/concerns/attribute_labels.rb
module AttributeLabels
extend ActiveSupport::Concern
class_methods do
def define_label_methods
column_names.each do |column|
define_method("#{column}_label") do
self.class.human_attribute_name(column)
end
end
end
end
included do
define_label_methods
end
end
# app/controllers/concerns/authenticatable.rb
module Authenticatable
extend ActiveSupport::Concern
included do
before_action :authenticate_user!
end
private
def current_organization
current_user.organizations.first
end
end
extend ActiveSupport::Concernincluded block for callbacks, scopes, associationsclass_methods block for class-level methods# BAD — display logic in concern (belongs in helper)
module Task::Display
extend ActiveSupport::Concern
def status_badge
case status
when "pending" then "badge-warning"
when "completed" then "badge-success"
end
end
def formatted_due_date
due_at&.strftime("%Y年%m月%d日")
end
end
# GOOD — move to app/helpers/tasks_helper.rb
# BAD — service class
class TaskService
def initialize(task)
@task = task
end
def process
@task.update!(status: :in_progress)
send_notification(@task)
end
end
# BAD — god concern (too many responsibilities)
module Task::Everything
# validations, notifications, transitions, exports, imports...
end
# GOOD — focused concerns
module Task::StatusTransitions # just status logic
module Task::Notifications # just notification logic
module Task::Exports # just export logic