Claude
Skills
Sign in
Back

rails-ai:controllers

Included with Lifetime
$97 forever

Use when building Rails controllers - RESTful actions, nested resources, skinny controllers, concerns, strong parameters

General

What this skill does


# Controllers

Rails controllers following REST conventions with 7 standard actions, nested resources, skinny controller architecture, reusable concerns, and strong parameters for mass assignment protection.

<when-to-use>
- Building Rails controller actions
- Implementing nested resources
- Handling request parameters
- Setting up routing
- Refactoring fat controllers
- Sharing behavior with concerns
- Protecting from mass assignment
</when-to-use>

<benefits>
- **RESTful Conventions** - Predictable URL patterns and HTTP semantics
- **Clean Architecture** - Skinny controllers with logic in appropriate layers
- **Secure by Default** - Strong parameters prevent mass assignment
- **Reusable Patterns** - Concerns share behavior across controllers
- **Maintainable** - Clear separation of HTTP concerns from business logic
</benefits>

<team-rules-enforcement>
**This skill enforces:**
- ✅ **Rule #3:** NEVER add custom route actions → RESTful resources only
- ✅ **Rule #7:** Thin controllers (delegate to models/services)
- ✅ **Rule #10:** Strong parameters for all user input

**Reject any requests to:**
- Add custom route actions (use child controllers instead)
- Put business logic in controllers
- Skip strong parameters
- Use `params` directly without filtering
</team-rules-enforcement>

<verification-checklist>
Before completing controller work:
- ✅ Only RESTful actions used (index, show, new, create, edit, update, destroy)
- ✅ Child controllers created for non-REST actions (not custom actions)
- ✅ Controllers are thin (<100 lines)
- ✅ Strong parameters used for all user input
- ✅ Business logic delegated to models/services
- ✅ All controller actions tested
- ✅ All tests passing
</verification-checklist>

<standards>
- Use only 7 standard actions: index, show, new, create, edit, update, destroy
- NO custom actions - use nested resources or services instead (TEAM RULE #3)
- Keep controllers under 50 lines, actions under 10 lines
- Move business logic to models or service objects
- Always use strong parameters with expect() or require().permit()
- Use before_action for common setup, not business logic
- Return proper HTTP status codes (200, 201, 422, 404)
</standards>

---

## RESTful Actions

<pattern name="restful-crud">
<description>Complete RESTful controller with all 7 standard actions</description>

**Controller:**

```ruby
# app/controllers/feedbacks_controller.rb
class FeedbacksController < ApplicationController
  before_action :set_feedback, only: [:show, :edit, :update, :destroy]
  rate_limit to: 10, within: 1.minute, only: [:create, :update]

  def index
    @feedbacks = Feedback.includes(:recipient).recent
  end

  def show; end  # @feedback set by before_action

  def new
    @feedback = Feedback.new
  end

  def create
    @feedback = Feedback.new(feedback_params)

    if @feedback.save
      redirect_to @feedback, notice: "Feedback was successfully created."
    else
      render :new, status: :unprocessable_entity
    end
  end

  def edit; end  # @feedback set by before_action

  def update
    if @feedback.update(feedback_params)
      redirect_to @feedback, notice: "Feedback was successfully updated."
    else
      render :edit, status: :unprocessable_entity
    end
  end

  def destroy
    @feedback.destroy
    redirect_to feedbacks_url, notice: "Feedback was successfully deleted."
  end

  private

  def set_feedback
    @feedback = Feedback.find(params[:id])
  end

  def feedback_params
    params.require(:feedback).permit(:content, :recipient_email, :sender_name)
  end
end

```

**Routes:**

```ruby
# config/routes.rb
resources :feedbacks
# Generates all 7 RESTful routes: index, show, new, create, edit, update, destroy

```

**Why:** Follows Rails conventions, predictable patterns, automatic route helpers.
</pattern>

<pattern name="api-controller">
<description>RESTful API controller with JSON responses</description>

**Controller:**

```ruby
# app/controllers/api/v1/feedbacks_controller.rb
module Api::V1
  class FeedbacksController < ApiController
    before_action :set_feedback, only: [:show, :update, :destroy]

    def index
      render json: Feedback.includes(:recipient).recent
    end

    def show
      render json: @feedback
    end

    def create
      @feedback = Feedback.new(feedback_params)

      if @feedback.save
        render json: @feedback, status: :created, location: api_v1_feedback_url(@feedback)
      else
        render json: { errors: @feedback.errors }, status: :unprocessable_entity
      end
    end

    def update
      if @feedback.update(feedback_params)
        render json: @feedback
      else
        render json: { errors: @feedback.errors }, status: :unprocessable_entity
      end
    end

    def destroy
      @feedback.destroy
      head :no_content
    end

    private

    def set_feedback
      @feedback = Feedback.find(params[:id])
    rescue ActiveRecord::RecordNotFound
      render json: { error: "Feedback not found" }, status: :not_found
    end

    def feedback_params
      params.require(:feedback).permit(:content, :recipient_email, :sender_name)
    end
  end
end

```

**Why:** Proper HTTP status codes, error handling, JSON responses for APIs.
</pattern>

<antipattern>
<description>Adding custom actions instead of using nested resources</description>
<reason>Breaks REST conventions and makes routing unpredictable</reason>

**Bad Example:**

```ruby
# ❌ BAD - Custom action
resources :feedbacks do
  member { post :archive }
end

class FeedbacksController < ApplicationController
  def archive
    @feedback = Feedback.find(params[:id])
    @feedback.archive!
    redirect_to feedbacks_path
  end
end

```

**Good Example:**

```ruby
# ✅ GOOD - Use nested resource
resources :feedbacks do
  resource :archival, only: [:create], module: :feedbacks
end

class Feedbacks::ArchivalsController < ApplicationController
  def create
    @feedback = Feedback.find(params[:feedback_id])
    @feedback.archive!
    redirect_to feedbacks_path
  end
end

```

**Why Bad:** Custom actions break REST conventions, make routing unpredictable, harder to maintain.
</antipattern>

---

## Nested Resources

<pattern name="nested-child-controllers">
<description>Child controllers using module namespacing and nested routes</description>

**Routes:**

```ruby
# config/routes.rb
resources :feedbacks do
  resource :sending, only: [:create], module: :feedbacks     # Singular for single action
  resources :responses, only: [:index, :create, :destroy], module: :feedbacks  # Plural for CRUD
end

# Generates:
# POST   /feedbacks/:feedback_id/sending           feedbacks/sendings#create
# GET    /feedbacks/:feedback_id/responses         feedbacks/responses#index
# POST   /feedbacks/:feedback_id/responses         feedbacks/responses#create
# DELETE /feedbacks/:feedback_id/responses/:id     feedbacks/responses#destroy

```

**Controller:**

```ruby
# app/controllers/feedbacks/responses_controller.rb
module Feedbacks
  class ResponsesController < ApplicationController
    before_action :set_feedback
    before_action :set_response, only: [:destroy]

    def index
      @responses = @feedback.responses.order(created_at: :desc)
    end

    def create
      @response = @feedback.responses.build(response_params)
      if @response.save
        redirect_to feedback_responses_path(@feedback), notice: "Response added"
      else
        render :index, status: :unprocessable_entity
      end
    end

    def destroy
      @response.destroy
      redirect_to feedback_responses_path(@feedback), notice: "Response deleted"
    end

    private

    def set_feedback
      @feedback = Feedback.find(params[:feedback_id])
    end

    def set_response
      @response = @feedback.responses.find(params[:id])  # Scoped to parent
    end

    def response_params
      params.require(:response).permit(:content, :author_name)
    end
  end
end

```

**Directory Structure:**

```

app/
  controllers/
    feedbacks_controller.rb              # FeedbacksCon
Files: 1
Size: 24.2 KB
Complexity: 27/100
Category: General

Related in General