inherit_mode: merge: - Exclude - IgnoredPatterns inherit_from: common_rubocop.yml # Enable additional Rails cops Rails: Enabled: true AllCops: Exclude: - 'bin/puma' - 'bin/pumactl' - 'bin/rails' - 'bin/shoryuken' - 'bin/sidekiq' - 'bin/sidekiqctl' - 'bin/spring' - 'db/schema.rb' - 'db/migrate/**/*' # Rails project's are not concerned with API docs normally Documentation: Enabled: false Metrics/BlockLength: Exclude: - 'config/routes.rb' - 'spec/rails_helper.rb' # Rails foreign keys and indexes can get long. We want to ignore our annotation # comments which are for these entries. # # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. # URISchemes: http, https Metrics/LineLength: IgnoredPatterns: - '\A# fk_rails_' - '\A# index_' # For our Rails apps several of them use the `respond_to` with `format` blocks # to handle various mime types (mostly HTML and JSON). Given our `do` / `end` # block style for non-functional blocks (which includes both `respond_to` and # `format`) the general method limit of is too small. This also applies to the # helper methods which define the allowed parameters for the action; especially # for larger forms. # # Here is an example of a minimal controller `update` method which uses the # `respond_to` style to support just the HTML and JSON formats: # # ```ruby # def update # respond_to do |format| # if @resource.update(resource_params) # format.html do # redirect_to resources_url, notice: 'Resource was successfully updated.' # end # format.json do # render :show, status: :ok, location: @resource # end # else # format.html do # render :edit # end # format.json do # render json: @resource.errors, status: :unprocessable_entity # end # end # end # end # ``` # # We do believe that the default size of 10, which is what we explicitly # configure below so there's no confusion, is a good general limit to help # encourage a balance between terseness and procedural code. Thus we do not # want to raise the limit, instead we just want to exclude these controllers. # # At this time there is no way for us to exclude just the common controller # actions / *_params methods so we exclude the entire file. # # Configuration parameters: CountComments. Metrics/MethodLength: Max: 10 Exclude: - 'app/controllers/**/*_controller.rb' # Ignore subclass parent for one off benchmarks # # Benchmarks are generally meant to be small and targeted. They often have # custom model declarations which help direct the focus of the benchmarks. # These one-off models exist outside of the main Rails app. We don't want this # cop to run for them because including `ApplicationRecord` is unnecessary in # these cases and just adds noise to the setup. Rails/ApplicationRecord: Exclude: - 'benchmarks/**/*' # As Rails defaults to creating timestamps you need to go out of your way to # explicitly have them removed from the table. This cop is almost always a # false negative so we're disabling it. # # Configuration parameters: Include. # Include: db/migrate/*.rb Rails/CreateTableWithTimestamps: Enabled: false # Usage of `find_by` is more expressive of intent than `where.first`. We should # check all app code, not just the models to improve intent expression. # # Since rake tasks often live in `lib` we also check all of lib as well. # # Configuration parameters: Include. # Include: app/models/**/*.rb Rails/FindBy: Enabled: true Include: - 'app/**/*.rb' - 'lib/**/*.rb' # Usage of `each` for large datasets can be a performance issue; specially a # drain on system memory. When possible it's better to use `find_each` so that # chunks of data are evaluated at a time. # # We should check all app code, not just the models to help prevent this. Since # rake tasks often live in `lib` we also check all of lib as well. # # Configuration parameters: Include. # Include: app/models/**/*.rb Rails/FindEach: Enabled: true Include: - 'app/**/*.rb' - 'lib/**/*.rb' # We understand the trade-offs for using the through model versus a lookup # table. As such this cop is just noise as it flags only those cases we really # do want a lookup table. # # Configuration parameters: Include. # Include: app/models/**/*.rb Rails/HasAndBelongsToMany: Enabled: false # The ActiveSupport monkey patches for `present?` are nearly all defined as: # # !blank? # # For most of us `unless blank?` reads just as easily as `if present?`. # Sometimes contextually, it can read better depending on the branch logic and # surrounding context. As `if present?` requires an additional negation and # method call it is technically slower. In the general case the perf difference # isn't much but in some cases it matters. Thus, we are not enforcing changing # `unless blank?` to `if present?` and are leaving it up to the context to # decide which is a better fit. # # Cop supports --auto-correct. # Configuration parameters: NotNilAndNotEmpty, NotBlank, UnlessBlank. Rails/Present: UnlessBlank: false # We prefer you use the attribute readers and writes. For those special cases # where the intent is really to interact with the raw underlying attribute we # prefer `read_attribute` and `write_attribute`; as this makes the intent # explicit. Ideally we'd never use the hash like accessor `[:attr]`. # # We disable this cop because it is not configurable. # # Configuration parameters: Include. # Include: app/models/**/*.rb Rails/ReadWriteAttribute: Enabled: false # This ensures we do not ignore potential validation issues in the code. Doing # so can lead to strange and surprising bugs where records are expected to # be created, or be modified, but are not. # # # If author is a new record the book may not be created since the FK is # # invalid. Perhaps omitting other fields, maybe new required fields, is # # an oversight in the book creation as well. # author.save # Book.create(author: author) # # Or side effects are expected to occur but they do not: # # # This is a condensed default Rails scaffold controller for `destroy`. # # # # Once a `has_many` or `has_one` associations is added which specifies # # `dependent: :restrict_with_error` this no longer behaves as expected. # # Given such associations are often added much later in time errors in # # this action are an all to common oversight in Rails. # def destroy # @book.destroy # respond_to do |format| # format.html do # redirect_to books_url, notice: 'Book was successfully destroyed.' # end # end # end # # Configuration parameters: AllowImplicitReturn, AllowedReceivers. Rails/SaveBang: Enabled: true # According to the Rails docs while the following methods skip validations they # only update the specified (single) attribute reducing risks. We'd rather not # warn for those cases: # # - decrement! # - increment! # - touch # # We are not excluding `toggle!` because it's more likely that a flag may have # validations associated with it (or is used by other validations). # # See: # # - http://api.rubyonrails.org/classes/ActiveRecord/CounterCache/ClassMethods.html # - http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html # - http://api.rubyonrails.org/classes/ActiveRecord/Relation.html # # Blacklist: decrement!, decrement_counter, increment!, increment_counter, toggle!, touch, update_all, update_attribute, update_column, update_columns, update_counters Rails/SkipsModelValidations: Blacklist: - 'decrement_counter' - 'increment_counter' - 'toggle!' - 'update_all' - 'update_attribute' - 'update_column' - 'update_columns' - 'update_counters' # Rails uses compact style by default so we're disabling this with a :hammer: # for things likely to be generated by Rails (i.e. most things in app). # # Configuration parameters: AutoCorrect, EnforcedStyle. # SupportedStyles: nested, compact Style/ClassAndModuleChildren: Exclude: - 'app/**/*'