[RUBY] [Rails] Bénéficiez de rubocop avec un minimum d'effort

introduction

C'était imprimé comme un sortilège, "Quand vous faites un projet de rails, mettons du rubocop", mais en fait, je ne comprenais pas exactement ce que rubocop peut faire et quels types d'avantages il a, alors je l'ai résumé.

La chose importante à garder à l'esprit lors de l'utilisation de ce genre d '"outil qui peut faire diverses choses" n'est pas de saisir toutes les fonctions fournies et de les utiliser toutes, mais de minimiser environ 80% qui répond à l'objectif de l'introduction. Je pense qu'il est important de pouvoir le faire avec l'effort de.

Ce serait formidable si vous pouviez lire cet article et obtenir le résultat non seulement de l'introduction de rubocop, mais aussi de l'amélioration de la qualité du code sans aucun effort (= se concentrer sur la logique et les tests qui devraient être écrits). ..

Qu'est-ce que le rubocop?

En un mot, c'est un outil qui inspecte le code dans ruby (fichier .rb) et détecte où il enfreint les règles.

Non seulement cela améliore la lisibilité du code, comme «le code est trop long» et «l'inden n'est pas approprié», mais cela conduit également à des bogues tels que «il n'y a pas d'options à clarifier» et «la base de données et le modèle sont incohérents». Il détecte également les violations de ces règles. Et dans de nombreux cas, il le réparera automatiquement.

De plus, si vous utilisez des rails, en utilisant simultanément rubocop-rails, les fichiers spécifiques aux rails (ex. Fichier de migration, fichier de configuration) seront également inspectés.

mérite

Je pense que les avantages (avantages) qui peuvent être obtenus en introduisant le rubocop sont les suivants.

Comment utiliser rubocop

Nous décrirons l'introduction et l'utilisation lors de l'utilisation de rails.

L'environnement que j'ai essayé est le suivant.

De plus, dans mon cas, il y avait une application de rails que j'ai créée avec la priorité de la créer, et je l'ai présentée avec environ 5 ou 6 modèles et contorllers créés.

De plus, j'ai gardé ce qui suit à l'esprit lors de son introduction. Donc, je pense qu'il y a des parties qui sont différentes du contenu du réglage et des parties incompatibles, ainsi que la méthode d'introduction décrite par d'autres personnes.

――Ne visez pas à 100% soudainement —— Laissez ce que fait l'outil à l'outil et concentrez-vous sur ce que vous devez faire

Installation et configuration

Faites la description suivante dans l'installation du Gemfile et du bundle

group :development do
  gem 'rubocop', require: false
  gem 'rubocop-rails'
end

Vérifiez pour le moment

$ rubocop
Inspecting 57 files
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

Offenses:
57 files inspected, 292 offenses detected, 260 offenses auto-correctable

292 pièces ont été foirées ... De plus, même si je serrais, je ne pouvais pas afficher tous les orz

Vérifiez celui-ci un par un et corrigez-le. Que faire? Je ne fais plus de rubocop! Il sera jeté, alors faisons-en un outil utile qui peut être utilisé en continu.

C'est pourquoi nous effectuons la "création du fichier de paramétrage" et la "correction automatique" suivantes.

Créer un fichier de configuration

Lorsque vous exécutez la commande suivante, il crée un fichier de paramètres (.rubocop.yml) et décrit le paramètre pour ignorer la violation de convention détectée dans ( .rubocop_todo.yml). ..

$ rubocop --auto-gen-config

Écrivez les règles et la portée à appliquer (non appliquées) dans le fichier de paramètres.

Pour le moment, j'ai essayé de mettre dans les paramètres suivants avec l'idée de "restreindre la cible de vérification au code que j'ai écrit".

AllCops:
  TargetRubyVersion: 2.6
  NewCops: enable    #← Jugement sur l'opportunité d'appliquer lors de l'enregistrement d'un nouvel accord
  Exclude:
    - 'bin/**'
    - 'node_modules/**/*'
    - 'config/**/*'
    - 'config.ru'
    - 'db/schema.rb'
    - 'db/seeds.rb'
    - 'Gemfile'

--Invalide ou modifiez les règles qui ne correspondent pas à votre méthode de description de code et ne nécessitent pas de détection d'erreur

#Autoriser les commentaires en japonais
Style/AsciiComments:
  Enabled: false

#Ignorer les exigences des commentaires de classe
Style/Documentation:
  Enabled: false

# 「frozen_string_literal:N'ajoutez pas «vrai»
Style/FrozenStringLiteralComment:
  Enabled: false

#Le nombre de lignes dans la méthode est trop strict jusqu'à 10 lignes, alors changez-le en 20 lignes
Metrics/MethodLength:
  Max: 20

# private/empreintes protégées plus profondes
Style/IndentationConsistency:
  EnforcedStyle: indented_internal_methods

Après avoir décrit ces fichiers de paramètres, commentez le contenu du fichier (.rubocop_todo.yml) qui a sauvé la violation des règles, et exécutez à nouveau rubocop. Dans mon cas, il est tombé à environ 50.

À ce stade, je n'ai toujours pas envie de tout réparer un par un, alors je vais effectuer la correction automatique suivante.

Correction automatique

Comme mentionné au début, les violations de convention simples (et claires) sont automatiquement corrigées avec la commande rubocop -a.

Lorsqu'elles sont exécutées, comme ceci, les violations de règle automatiquement corrigées recevront «[Corrected]», et enfin, le nombre de règles corrigées automatiquement sera affiché pour le nombre total de violations de règle.

$ rubocop -a
.rubocop.yml: Style/IndentationConsistency has the wrong namespace - should be Layout
Inspecting 29 files
....................CC.CCCCCC

Offenses:

db/migrate/20200928124523_devise_create_users.rb:6:59: C: [Corrected] Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
      t.string :nickname,           null: false, default: ""
                                                          ^^

~Omis en chemin ~

29 files inspected, 24 offenses detected, 22 offenses corrected

Correction manuelle

Et, la violation des règles qui subsiste même après la correction automatique doit être traitée par vous-même (= ** le travail que je voulais faire à l'origine, prenez le temps de comprendre le contenu et corrigez-le au code qui devrait être **) est.

Dans mon cas, les deux suivants sont restés. Je pense que c'est une violation des règles qui peut conduire à des bogues, alors vérifiez le contenu de l'erreur (ex. Si vous recherchez sur Google avec le mot-clé Rails / HasManyOrHasOneDependent, vous pouvez le trouver dans le contenu du site officiel ou dans l'article de commentaire poli) , J'ai examiné la méthode de correction, je l'ai corrigée et j'ai exécuté à nouveau rubocop, et il était prudent de violer les règles.

# has_Option dépendante pour de nombreuses associations(Lors de la suppression de l'enregistrement parent, le supprimer en même temps? partir? Faire une erreur? Donnez-vous un avertissement? ) N'est pas défini
app/models/category.rb:3:3: C: Rails/HasManyOrHasOneDependent: Specify a :dependent option.
  has_many :estimate_details
  ^^^^^^^^

#La validation unique est définie dans le modèle, mais unique n'est pas définie dans la définition de la base de données
app/models/category.rb:6:3: C: Rails/UniqueValidationWithoutIndex: Uniqueness validation should be with a unique index.
  validates :user_id, uniqueness: { scope: :category_name }

Exécution automatique

C'est un outil utile, mais n'oubliez pas de l'exécuter en premier lieu, alors exécutons-le automatiquement lorsque quelque chose se produit. Je pense que le meilleur timing est le timing de commit, donc je vais introduire un gem appelé pre-commit afin qu'il soit automatiquement exécuté lorsque la commande git commit est émise.

--Installation du pré-commit

Définissez gem pre-commit sur Gemfile, et après bundle install, générez un fichier de pré-commit avec la commande suivante.

$ pre-commit install
Installed /Users/hiro/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/pre-commit-0.39.0/templates/hooks/automatic to .git/hooks/pre-commit

Pour exécuter automatiquement rubocop au moment de la validation, définissez avec la commande suivante.

#Vérifiez l'état avant de régler
$ pre-commit list    
Available providers: default(0) git(10) git_old(11) yaml(20) env(30)
Available checks   : before_all ci coffeelint common console_log csslint debugger gemfile_path go go_build go_fmt jshint jslint json local merge_conflict migration nb_space pry rails rspec_focus rubocop ruby ruby_symbol_hashrockets scss_lint tabs whitespace yaml
Default   checks   : common rails
Enabled   checks   : common rails
Evaluated checks   : tabs nb_space whitespace merge_conflict debugger pry local jshint console_log migration
Default   warnings : 
Enabled   warnings : 
Evaluated warnings :

#Défini pour exécuter rubocop au moment de git commit
$ git config pre-commit.checks rubocop

#Vérifiez l'état après le réglage
$ pre-commit list    
Available providers: default(0) git(10) git_old(11) yaml(20) env(30)
Available checks   : before_all ci coffeelint common console_log csslint debugger gemfile_path go go_build go_fmt jshint jslint json local merge_conflict migration nb_space pry rails rspec_focus rubocop ruby ruby_symbol_hashrockets scss_lint tabs whitespace yaml
Default   checks   : rubocop   #← rubocop est réglé
Enabled   checks   : rubocop   #← rubocop est réglé
Evaluated checks   : rubocop   #← rubocop est réglé
Default   warnings : 
Enabled   warnings : 
Evaluated warnings :

De plus, lors de l'utilisation de pre-commti via bundle, il est nécessaire de modifier le fichier de configuration (.git / hooks / pre-commit) sous .git comme suit.

#!/usr/bin/env sh

~ Omis ~

PATH=$PATH:/usr/local/bin:/usr/local/sbin

cmd=`git config pre-commit.ruby 2>/dev/null`
if   test -n "${cmd}"
then true
elif which rvm   >/dev/null 2>/dev/null
then cmd="rvm default do ruby"
elif which rbenv >/dev/null 2>/dev/null
then cmd="rbenv exec ruby"  #← Avant correction
then cmd="rbenv exec bundle exec ruby"  #← Après correction
else cmd="ruby"
fi

~ Omis ~

Après avoir terminé les paramètres, exécutez la commande git commit et vérifiez si rubocop est automatiquement exécuté.

(La marge de fin de ligne a été préparée à l'avance afin que les règles soient violées.)

$ git commit
pre-commit: Stopping commit because of errors.
Inspecting 1 file
C

Offenses:

app/controllers/home_controller.rb:4:1: C: Layout/TrailingWhitespace: Trailing whitespace detected.

1 file inspected, 1 offense detected, 1 offense auto-correctable
.rubocop.yml: Style/IndentationConsistency has the wrong namespace - should be Layout

pre-commit: You can bypass this check using `git commit -n`

J'ai pu confirmer que rubocop est automatiquement exécuté au moment de la validation. Si une violation est détectée, le processus de validation sera interrompu.

Comme le flux après détection, je pense que ce sera le flux de "confirmation du contenu de la violation" → (s'il doit être corrigé) "correction manuelle ou automatique ( rubocop -a) "→" registre dans l'environnement de test "→" commit " Je vais.

en conclusion

À l'avenir, rubocop fonctionnera automatiquement pour la validation, et il peut être configuré pour être vérifié et peut être utilisé en continu. Si vous pouvez écrire du code et revoir le fichier de paramètres ou vérifier le contenu et changer le style d'écriture lorsqu'une nouvelle violation de règle se produit, je pense que vous pouvez développer un meilleur outil et le vôtre Je pense que cela peut conduire à améliorer la qualité du code.

Articles que j'ai utilisés comme référence

J'ignorais complètement comment l'utiliser, donc c'était très utile. Nous aimerions profiter de cette occasion pour remercier les auteurs de l'article.

--Comment utiliser rubocop https://kitsune.blog/rails-rubocop https://qiita.com/tomohiii/items/1a17018b5a48b8284a8b

--Introduction du pré-engagement https://techblog.kyamanak.com/entry/2018/06/19/221910 https://dev.classmethod.jp/articles/pre-commit-rubocop/

Recommended Posts

[Rails] Bénéficiez de rubocop avec un minimum d'effort
Je veux jouer avec Firestore de Rails
[Rails 6] Erreur d'exécution avec $ rails s
Manipuler le dispositif avec des rails
[Rails] Didacticiel Apprendre avec les rails
[Rails] Test avec RSpec
[Rails] Développement avec MySQL
Prend en charge la multilinguisme avec Rails!
Cloud9 (Rails) de Github
[Rails] Recherche à partir de plusieurs colonnes + conditions avec Gem et ransack