[RUBY] J'ai essayé de comprendre comment la méthode des rails "link_to" est définie

J'ai appris d'un ingénieur d'élite sur le lieu de travail que lire un bon code sera un catalyseur pour grandir en tant qu'ingénieur, alors je le mets en pratique immédiatement! Je vais le partager en passant.

En apprenant un bon code, vous serez en mesure d'écrire du code hautement lisible et comportant peu de bogues, veuillez donc vous y référer également.

Commencez par link_to.

Définition de link_to

def link_to(name = nil, options = nil, html_options = nil, &block)
  html_options, options, name = options, name, block if block_given?
  options ||= {}

  html_options = convert_options_to_data_attributes(options, html_options)

  url = url_for(options)
  html_options["href"] ||= url

  content_tag("a", name || url, html_options, &block)
end

Depuis l 'API officielle de Ruby on Rails, changez le nom (si block = do ~ end n'est pas utilisé) La chaîne de caractères à afficher, les informations d'url dans les options et la valeur que vous souhaitez définir dans le code HTML, une balise telle que class et rel sont passées dans html_options.

Il est supposé que les options et html_options sont passées au format de hachage.

Immédiatement, j'ajouterai l'interprétation ligne par ligne.

def link_to(name = nil, options = nil, html_options = nil, &block)

La description de = nil dans la définition de l'argument signifie que lorsqu'aucune valeur n'est affectée, nil est affecté à l'argument concerné. & Block dans le 4ème argument est une description de la réception d'un "bloc". Si vous lisez cet article, un bloc est utilisé lors du passage d'un morceau de code, pas une valeur comme argument ***. *** Il semble que le morceau de code passé s'appelle un bloc ***.

Lors de l'écriture de link_to do ~ end, ~ est remplacé ici.

Ligne suivante

html_options, options, name = options, name, block if block_given?

block_given? (Manuel de référence Ruby) À partir du manuel de référence, block_given? Devient vrai lorsque le bloc est passé à la méthode link_to et que le contenu de l'instruction if est exécuté. En d'autres termes, il s'agit de Multiple Assignment (Ruby Reference).

Par exemple, lors de l'utilisation de block, depuis Ruby on Rails Official API

link_to(options = {}, html_options = {}) do
  # name
end

Sera décrit comme Dans ce cas, les options (informations d'url) seront passées à name, qui est à l'origine le nom d'affichage, et html_options, qui définit la classe et l'id, sera passé aux options, qui sont des informations d'url, à partir de la première ligne de la définition link_to.

Par conséquent, le rôle de cette ligne est de réaffecter comme défini par la méthode afin qu'elle fonctionne comme l'utilisateur de la méthode l'a prévu. (Par exemple, la valeur du nom à laquelle les informations d'url ont été attribuées est réaffectée aux options)

Suivant

options ||= {}

||=Est une description que la valeur du côté droit est attribuée lorsque le côté gauche est faux ou n'est pas défini. Dans la première ligne, lorsqu'aucune valeur n'est passée à l'argument, nil est affecté aux options, donc le contenu des options est nul, c'est-à-dire faux. À ce stade, {} (hachage vide) est attribué aux optins.

html_options = convert_options_to_data_attributes(options, html_options)

Une méthode appelée convert_options_to_data_attributes est appelée.

Lecture de la méthode convert_options_to_data_attributes

La définition de cette méthode est lien ici

def convert_options_to_data_attributes(options, html_options)
  if html_options
    html_options = html_options.stringify_keys
    html_options["data-remote"] = "true".freeze if link_to_remote_options?(options) || link_to_remote_options?(html_options)

    method = html_options.delete("method".freeze)

    add_method_to_attributes!(html_options, method) if method

    html_options
  else
    link_to_remote_options?(options) ? { "data-remote" => "true".freeze } : {}
  end
end

Lisons convert_options_to_data_attributes.

La troisième ligne est exécutée si html_options est présent.

html_options = html_options.stringify_keys

stringfy_keys est une méthode rails qui convertit un hachage du format symbolique au format chaîne.

4ème ligne

html_options["data-remote"] = "true".freeze if link_to_remote_options?(options) || link_to_remote_options?(html_options)

En bref, si options ou html_options a un paramètre remote: true, true sera attribué à la clé data-remote au format chaîne.

Vous pouvez comprendre pourquoi cela se produit si vous pouvez comprendre le contenu de link_to_remote_options? De la méthode rails. J'expliquerai en détail dans l'interprétation de la déclaration else, alors veuillez vous y référer d'abord.

5ème ligne

method = html_options.delete("method".freeze)

Delete pour le hachage supprime la clé qui correspond à la valeur de l'argument → renvoie la valeur de clé supprimée Masu L'argument est la méthode ".freeze. freeze ne supprime pas la première fonction de suppression, mais la deuxième fonction. , Autrement dit, ne renvoie que la valeur de method.

Par conséquent, la valeur de la méthode clé de html_options est affectée à la méthode variable. (Valeur de réglage de la méthode HTML) Cette façon d'écrire est intéressante.

6ème ligne

add_method_to_attributes!(html_options, method) if method

De plus, si la valeur de method est définie, appelez add_method_to_attributes! Method. Puisqu'il a un! Mark, c'est une méthode destructive.

add_method_to_attributes! méthode

La méthode add_method_to_attributes! Est définie comme suit.

def add_method_to_attributes!(html_options, method)
  if method_not_get_method?(method) && html_options["rel"] !~ /nofollow/
    if html_options["rel"].blank?
      html_options["rel"] = "nofollow"
    else
      html_options["rel"] = "#{html_options["rel"]} nofollow"
    end
  end
  html_options["data-method"] = method
end

Add_method_to_attributes! Lecture de méthode

add_method_to_attributes! Méthode 2ème ligne.

L'expression conditionnelle de if est une condition AND. Un élément de la condition AND est le retour de method_not_get_method? Method valeur.

L'expression de définition de cette méthode est omise, mais comme son nom l'indique, true est renvoyé pour les méthodes autres que get (comme delete). (C'est la méthode de nommage qui est également sur le code lisible!)

Le deuxième élément de la condition AND est le troisième élément de la section! De la référence Ruby. Vrai si la valeur de la clé rel dans html_options n'est pas nofollow.

add_method_to_attributes! lignes de méthode 3-7

Exécuté lorsque la condition AND mentionnée ci-dessus est satisfaite.

if html_options["rel"].blank?
  html_options["rel"] = "nofollow"
else
  html_options["rel"] = "#{html_options["rel"]} nofollow"
end

Allons-y tout de suite. Lorsque la valeur de la clé rel de html_options est vide, la chaîne de caractères nofollow est affectée. Si la valeur de la clé rel de html_options contient une valeur, ajoutez la chaîne de caractères nofollow en plus de la valeur définie.

Lorsqu'il est interprété en combinaison avec l'instruction if sur la deuxième ligne, rel = "nofollow" est défini pour les méthodes autres que get, que la valeur soit définie ou non dans rel.

À propos, la signification de nofollow est ["Exclure les liens de l'exploration"](https://www.seohacks.net/blog/column/1140/#:~:text=rel%3D%E2%80%9Dnofollow%E2 % 80% 9D% E3% 81% AE% E6% 84% 8F% E5% 91% B3,% E3% 81% AA% E3% 81% 8F% E3% 81% AA% E3% 82% 8B% E3% 81% A8% E3% 81% 84% E3% 81% 86% E3% 81% 93% E3% 81% A8% E3% 81% A7% E3% 81% 99% E3% 81% AD% E3% 80% 82) C'est vrai.

Je ne sais pas pourquoi il vaut mieux ajouter nofollow à des méthodes autres que get, et je ne peux que deviner, alors je vais l'omettre. Pour plus d'informations sur l'utilisation de rel lui-même, voir [ici](https://saruwakakun.com/html-css/basic/link-rel#:~:text=%E2%86%91%20rel%E3%81%AF%E3 % 80% 8Crelation% EF% BC% 88% E9% 96% A2% E4% BF% 82,% E3% 81% A7% E7% A4% BA% E3% 81% 99% E3% 82% 8F% E3% 81% 91% E3% 81% A7% E3% 81% 99% E3% 81% AD% E3% 80% 82)

add_method_to_attributes! Méthode 8ème ligne.

html_options["data-method"] = method

Au contraire, lorsque la méthode get est spécifiée, l'instruction if de la deuxième ligne se branche dans l'instruction else. Le code ci-dessus sera exécuté.

Le type de méthode HTTP est affecté à la clé "data-method" de html_options. Puisqu'il s'agit de "données-", il est défini comme un attribut personnalisé.

Enfin, l'interprétation de la méthode add_method_to_attributes! Est terminée.

Revenir à la lecture convert_options_to_data_attributes

(Republier)

def convert_options_to_data_attributes(options, html_options)
  if html_options
    html_options = html_options.stringify_keys
    html_options["data-remote"] = "true".freeze if link_to_remote_options?(options) || link_to_remote_options?(html_options)

    method = html_options.delete("method".freeze)

    add_method_to_attributes!(html_options, method) if method

    html_options
  else
    link_to_remote_options?(options) ? { "data-remote" => "true".freeze } : {}
  end
end

7ème ligne.

Renvoie le hachage html_options avec les deux valeurs affectées aux lignes 4 et 6.

Lignes 8-9

Si aucune valeur n'est passée à html_options

link_to_remote_options?(options) ? { "data-remote" => "true".freeze } : {}

Est exécuté.

C'est un opérateur ternaire. Tout d'abord, link_to_remote_options? est appelé.

def link_to_remote_options?(options)
  if options.is_a?(Hash)
    options.delete("remote".freeze) || options.delete(:remote)
  end
end

link_to_remote_options? méthode

Lorsque la valeur des options est un hachage, le contenu de l'instruction if est exécuté

Cependant, même si remote est défini, si remote: false est défini, la valeur d'un élément sera false. Deux éléments y sont appelés, et cette fois, le paramètre distant est supprimé car il n'y a pas de description de gel.

En bref, link_to_remote_options? Renvoie false si OU false n'est pas spécifié, et true si la valeur de remote est true.

Encore une fois, lisez l'instruction else de la méthode convert_options_to_data_attributes

Si true est renvoyé dans un élément par l'opérateur ternaire, c'est-à-dire que remote: true est défini, le symbole "data-remote" => true est la valeur de retour de convert_options_to_data_attributes.

La raison pour laquelle la valeur de la clé data-remote de html_options est définie dans l'une des instructions if de convert_options_to_data_attributes est que l'attribut personnalisé est défini indépendamment du fait que la valeur de paramètre distant soit transmise à l'argument de la méthode link_to, aux options ou à html_options. Il semble que la valeur de remote soit affichée en html.

Le modèle d'écriture du passage de la valeur à link_to est omis ici.

Revenir à link_to

(Republier)

def link_to(name = nil, options = nil, html_options = nil, &block)
  html_options, options, name = options, name, block if block_given?
  options ||= {}

  html_options = convert_options_to_data_attributes(options, html_options)

  url = url_for(options)
  html_options["href"] ||= url

  content_tag("a", name || url, html_options, &block)
end

Jusqu'à la 4ème ligne, la valeur de html_options a été formatée.

Vient ensuite la 5ème ligne.

url = url_for(options)

La méthode url_for est appelée.

def url_for(options)
    if options[:only_path]
      path_for options
    else
      full_url_for options
    end
end

path_for est une méthode qui génère un chemin relatif et full_url_for est une méthode qui génère un chemin absolu. Affiche le chemin d'accès relatif lorsque la valeur de la clé d'option only_path est true.

6ème ligne de link_to

html_options["href"] ||= url

Remplacez le chemin généré par la clé href de html_options. Ce que vous pouvez voir, c'est que vous pouvez spécifier de force l'URL en utilisant href comme clé pour le troisième facteur de link_to.

Qu'il soit utilisé ou non ...

Dernière 7ème ligne

content_tag("a", name || url, html_options, &block)

[content_tag est une aide à la vue]. (https://apidock.com/rails/ActionView/Helpers/TagHelper/content_tag) Produit la balise html.

Le premier argument est le type de balise html, dans ce cas .

Le deuxième argument est la chaîne de caractères à afficher. Dans ce cas, si le nom n'existe pas, l'URL sera automatiquement affichée sous forme de chaîne de caractères.

Si vous transmettez la classe: "XXX" etc. au format de hachage à html_options, elle sera affichée sous forme de texte .

De plus, comme vous pouvez le voir dans la description et le bloc, si un bloc est passé à link_to (s'il est écrit au format link_to ~ do ~ end), le bloc est passé à content_tag tel quel.

C'est la fin de la lecture de link_to.

Écoulement brutal

① Organisez l'ordre des arguments assignés ② Mettre en forme des valeurs telles que l'url et la méthode ③ Afficher avec content_tag

c'est tout.

Impressions que j'ai essayées cette fois

** Premier point ** En connaissant la définition de la méthode en premier lieu, il semble que vous serez en mesure de produire comme prévu. Par exemple, si vous utilisez une aide à la vue, vous pouvez réduire l'effort d'écriture du code par essais et erreurs - création et sortie de l'affichage souhaité.

** Deuxième point ** ||=Ou&J'avais vu comment écrire un bloc, mais j'ai réussi à écrire le code sans lui, donc je n'ai pas compris le sens et c'était une bonne opportunité.

Par exemple||=Cela signifie que si la variable est indéfinie ou nulle, elle sera affectée, mais si vous l'écrivez sans le savoir, vous pouvez simplement l'exprimer sur une ligne où vous écririez de manière compliquée en utilisant l'instruction if.

Comme je l'ai mentionné au début, en apprenant à écrire du bon code intelligent, vous serez en mesure d'écrire du code facile à maintenir et moins sujet aux erreurs.


Je continuerai d'apprendre dans le futur!

Recommended Posts

J'ai essayé de comprendre comment la méthode des rails "link_to" est définie
J'ai essayé de comprendre comment la méthode des rails "redirect_to" est définie
Comment utiliser la méthode link_to
[Rails] Comment utiliser la méthode de la carte
[Rails] Comment omettre l'affichage de la chaîne de caractères de la méthode link_to
[Rails] J'ai essayé de faire passer la version de Rails de 5.0 à 5.2
J'ai essayé d'organiser la session en Rails
[Rails] Je ne sais pas comment utiliser le modèle ...
[Rails] J'ai essayé d'utiliser la méthode button_to pour la première fois
Comment utiliser la méthode include?
[Rails] J'ai essayé de supprimer l'application
Tri des données Décroissant, croissant / Rails
J'ai essayé d'implémenter la fonction de prévisualisation d'image avec Rails / jQuery
[Java] J'ai essayé de faire un labyrinthe par la méthode de creusage ♪
J'ai essayé de résumer les méthodes utilisées
[Java] Comment utiliser la méthode toString ()
Comment avoir des paramètres dans la méthode link_to
J'ai essayé d'implémenter le modèle Iterator
J'ai essayé de résumer l'API Stream
Qu'est-ce que Docker? J'ai essayé de résumer
Emplacement de la définition de la méthode Résumé de la vérification Lorsque défini dans le projet et Rails / Gem
[Rails] Comment utiliser la méthode d'assistance, confimartion
[Introduction à Java] J'ai essayé de résumer les connaissances que j'estime essentielles
[Rails] Comment résoudre le décalage temporel de created_at après la méthode de sauvegarde
Sortie de la façon d'utiliser la méthode slice
Code utilisé pour connecter Rails 3 à PostgreSQL 10
Comment utiliser la méthode replace () (Java Silver)
J'ai essayé de configurer tomcat pour exécuter le servlet.
Comment vérifier les commandes Rails dans le terminal
[Introduction à Ruby] Comment utiliser la méthode slice
[Rails / ActiveRecord] Je souhaite valider la valeur avant la conversion du type (_before_type_cast)
[JavaScript] Le cas le plus fort lorsque j'ai essayé de résumer les parties que je ne comprends pas
[Rails] Comment utiliser la méthode d'assistance utilisée dans l'application principale avec Administrer
[JDBC ③] J'ai essayé d'entrer à partir de la méthode principale en utilisant des espaces réservés et des arguments.
[Rails] Comment se connecter à une API externe à l'aide du client HTTP (j'ai essayé de me connecter à l'API Qiita)
Comment régler l'heure d'affichage sur l'heure japonaise dans les rails
[rails] Comment utiliser la méthode d'assistance de devise before_action: authenticate_user!
[Ruby on Rails] Comment changer le nom de la colonne
05. J'ai essayé de supprimer la source de Spring Boot
J'ai essayé de réduire la capacité de Spring Boot
[Rails] Comment changer le nom de colonne de la table
Comment désinstaller Rails
J'ai essayé de résumer divers link_to utilisés cette fois
Rails6 J'ai essayé d'introduire Docker dans une application existante
[Rails] Je souhaite afficher la destination du lien de link_to dans un onglet séparé
Je veux appeler la méthode principale en utilisant la réflexion
[Rails] Comment obtenir le contenu des paramètres forts
[Commentaire approximatif] Je veux épouser la méthode du pluck