Class: RuboCop::Cop::Thoughtbot::ResourcefulActions

Inherits:
Base
  • Object
show all
Defined in:
lib/rubocop/cop/thoughtbot/resourceful_actions.rb

Overview

Checks for public methods in Rails controllers outside the seven resourceful actions: index, show, new, edit, create, update and destroy.

A custom action needs a custom route, and custom routes pick their verbs ad hoc (update-password, add-payment-method, activate) so no two read the same way. Sticking to the seven constrains you to the standard HTTP verbs and pushes the naming into nouns, which are far less ambiguous than invented verbs. It also keeps controllers small, since the fix for a new action is a new controller.

Rails routes any public instance method on a controller, so this cop also flags helpers left public. Those should be private.

Controllers dictated by a gem (Devise::OmniauthCallbacksController with an action per provider, or Doorkeeper's OAuth endpoints) can't follow the convention. Exclude them:

Thoughtbot/ResourcefulActions:
Exclude:
  - "app/controllers/users/omniauth_callbacks_controller.rb"

See https://thoughtbot.com/blog/in-relentless-pursuit-of-rest-ish-routing

Examples:

# bad
class UsersController < ApplicationController
  def activate
  end
end

# good
class Users::ActivationsController < ApplicationController
  def create
  end
end

# bad
class ApplicationController < ActionController::Base
  def current_user
  end
end

# good
class ApplicationController < ActionController::Base
  private

  def current_user
  end
end

Constant Summary collapse

MSG =
"`%<name>s` is not one of the seven resourceful actions (index, " \
"show, new, edit, create, update, destroy) — rename it, extract " \
"another controller, or make it private if it isn't an action. " \
"See https://thoughtbot.com/blog/in-relentless-pursuit-of-rest-ish-routing"
RESOURCEFUL_ACTIONS =
%i[index show new edit create update destroy].freeze
VISIBILITY_MODIFIERS =
%i[public protected private].freeze

Instance Method Summary collapse

Instance Method Details

#on_class(node) ⇒ Object



66
67
68
69
70
71
72
73
# File 'lib/rubocop/cop/thoughtbot/resourceful_actions.rb', line 66

def on_class(node)
  return unless controller?(node)
  return unless node.body

  non_resourceful_actions(node.body).each do |action|
    add_offense(action.loc.name, message: format(MSG, name: action.method_name))
  end
end