Guide pratique Ruby on Rails6 [Extensions] cp10 ~ cp12 [Memo]

introduction

L'auteur de cet article est un débutant qui commence à peine à apprendre la programmation. Je vous serais reconnaissant si vous pouviez signaler des erreurs.

Aperçu

Cet article est un mémo personnel de ce que j'ai appris en lisant le Guide pratique de Ruby on Rails 6. Il semble difficile à lire car il est extrait et repris. Excusez-moi. Ce livre a également une suite Extension, et les deux ont été étudiés au stade de la rédaction de l'article. J'écrirai également un article pour examen. Je vais sauter cp1 et cp2 de l'extension de fonction car ils expliquent la construction de l'environnement et le code de la partie principale. Cet article est le dernier.

Article précédent Guide pratique Ruby on Rails6 cp4 ~ cp6 [Memo] Guide pratique Ruby on Rails6 cp7 ~ cp9 [Memo] Guide pratique Ruby on Rails6 cp10 ~ cp12 [Memo] Guide pratique Ruby on Rails6 cp13 ~ cp15 [Memo] Guide pratique Ruby on Rails6 cp16 ~ cp18 [Memo] Guide pratique de Ruby on Rails6 [Extensions] cp3 ~ cp5 [Memo] Ruby on Rails6 Practical Guide [Extensions] cp7 ~ cp9 [Memo]

Extension des fonctions Chapitre 10 Ajax

Renvoie du texte comme réponse

render plain: Message.unprocessed.count

Référence: Rails Guide


JavaScript C'est un programme qui vérifie et met à jour le nombre de nouvelles demandes chaque minute.

function update_number_of_unprocessed_messages() {
  const elem = $("#number-of-unprocessed-messages")
  $.get(elem.data("path"), (data) => {
    if (data === "0") elem.text("")
    else elem.text("(" + data + ")")
  })
  .fail(() => window.location.href = "/login")
}

$(document).ready(() => {
  if ($("#number-of-unprocessed-messages").length)
    window.setInterval(update_number_of_unprocessed_messages, 1000 * 60)
})

La partie méthode $ .get de JQuery est écrite dans le modèle suivant.

  $.get(X, (data) => {
    Y
  })
  .fail(Z)

L'URL de l'API qui accède à X avec Ajax et le code que Y reçoit le résultat de l'accès et s'exécute. Les données renvoyées par l'API sont stockées dans les données d'argument et vous pouvez faire référence à cette valeur dans Y. Si .fail (Z) est spécifié, Z sera exécuté lorsque l'accès par Ajax échouera.

window.setInterval est une méthode qui appelle la fonction spécifiée dans le premier argument à intervalles réguliers.


Rejeter toutes les demandes sauf Ajax

raise ActionController::BadRequest unless request.xhr?

xhr? Détermine si la demande provient d'Ajax.

Extension des fonctions Chapitre 11 Arborescence

Afficher la chaîne de caractères omise

= truncate(content, length: 20)

La méthode truncate omet la chaîne passée à l'argument et l'affiche. La valeur par défaut est de 30 caractères.


Afficher l'arborescence des messages

app/presenters/message_presenter.rb


def tree
  expand(object.root || object)
end

def expand(node)
    markup(:ul) do |m|
      m.li do
        if node.id == object.id
          m.strong(node.subject)
        else
          m << link_to(node.subject, view_context.staff_message_path(node))
        end
        node.children.each do |c|
          m << expand(c)
        end
      end
    end
  end

expand est défini comme une méthode récursive. Vous vous appelez dans une méthode. Il met l'accent uniquement sur le sujet de l'objet principal affiché sur cette page et génère des liens à partir de ses objets parent et enfant. Nous appelons expand pour les enfants de cet objet dans l'ordre à partir de la racine. En conséquence, le HTML est généré dans l'ordre à partir de la racine et l'arbre est représenté.


Amélioration des performances

Le code ci-dessus peut également représenter l'arborescence, mais plus la structure est profonde, plus la base de données est accessible.

app/lib/simple_tree.rb


class SimpleTree
  attr_reader :root, :nodes

  def initialize(root, descendants)
    @root = root
    @descendants = descendants

    @nodes = {}
    ([ @root ] + @descendants).each do |d|
      d.child_nodes = []
      @nodes[d.id] = d
    end

    @descendants.each do |d|
      @nodes[d.parent_id].child_nodes << @nodes[d.id]
    end
  end
end

Une classe pour gérer les données structurées en arborescence. Le premier argument du constructeur est l'objet racine et le second argument est son objet descendant. Je crée un hachage @ nodes '' avec tous les objets appartenant à l'arbre comme valeurs. Chaque objet a un tableau d'objets descendants `` child_nodes```.

modèle

app/models/message.rb


attr_accessor :child_nodes

def tree
  return @tree if @tree
  r = root || self
  messages = Message.where(root_id: r.id).select(:id, :parent_id, :subject)
  @tree = SimpleTree.new(r, messages)
end

Définit child_nodes pour la gestion des objets enfants. Dans les messages, les objets autres que la racine appartenant à l'arborescence sont définis. Je crée un objet SimpleTree.

Réécrivez la méthode d'arborescence de MessagePresenter.

app/presenters/message_presenter.rb


def tree
  expand(object.tree.root) #Changement
end

def expand(node)
    markup(:ul) do |m|
      m.li do
        if node.id == object.id
          m.strong(node.subject)
        else
          m << link_to(node.subject, view_context.staff_message_path(node))
        end
        node.child_nodes.each do |c| #Changement
          m << expand(c)
        end
      end
    end
  end

Le nombre de requêtes vers la base de données a été réduit.

Extension des fonctions Chapitre 12 étiquetage

La création de balises à l'aide de Tag-it est omise.

Créer une table pour un contrôle exclusif

def change
    create_table :hash_locks do |t|
      t.string :table, null: false
      t.string :column, null: false
      t.string :key, null: false

      t.timestamps
    end

    add_index :hash_locks, [ :table, :column, :key ], unique: true
  end

Créez des données de départ à utiliser en production.

db/seeds/hash_locks.rb


256.times do |i|
  HashLock.create!(table: "tags", column: "value", key: sprintf("%02x", i))
end

La table cible est spécifiée dans l'attribut table et la colonne cible est spécifiée dans l'attribut colonne. L'expression clé `sprintf ("% 02x ", i)` `renvoie les nombres hexadécimaux à deux chiffres" 00 "à" ff "sous forme de chaîne.

Ajoutez une méthode de classe à la classe HashLock.

app/models/hash_lock.rb


class HashLock < ApplicationRecord
  class << self
    def acquire(table, column, value)
      HashLock.where(table: table, column: column,
        key: Digest::MD5.hexdigest(value)[0,2]).lock(true).first!
    end
  end
end

La méthode de classe Digest :: MD5 hexdigest génère une valeur de hachage à partir de la valeur donnée dans l'argument et la renvoie sous la forme d'un nombre hexadécimal à 32 chiffres. La même valeur de hachage est générée à partir de la même chaîne. Trouvez l'enregistrement avec les deux premiers chiffres de la clé hexadécimale générée et obtenez un verrou exclusif.

Utilisez HashLock.aquire

app/models/message.rb


def add_tag(label)
    self.class.transaction do
      HashLock.acquire("tags", "value", label)
      tag = Tag.find_by(value: label)
      tag ||= Tag.create!(value: label)
      unless message_tag_links.where(tag_id: tag.id).exists?
        message_tag_links.create!(tag_id: tag.id)
      end
    end
  end

Il évite les conflits de balises en acquérant des verrous exclusifs sur les enregistrements de la table hash_locks.

Délai d'utilisation de HashLock

Si ces deux conditions sont remplies, les conditions pour la même condition de course seront remplies.

Impressions

Le total des deux livres était d'environ 850 pages, mais j'ai pu terminer la course pendant deux semaines sans copier. C'était extrêmement difficile par rapport au tutoriel Rails, mais je ne comprends pas l'explication, probablement à cause de mon expérience de développement App! Cela ne s'est pas produit et j'ai réussi à continuer. Je me suis en outre rappelé mon manque de connaissances. C'est plus difficile pour les débutants, mais je suis content de l'avoir lu car il regorge de savoir-faire pratique. Je vais continuer à étudier dur.

Source du devis

Recommended Posts

Ruby on Rails6 Guide pratique [Extensions] cp7 ~ cp9 [Mémo]
Guide pratique Ruby on Rails6 [Extensions] cp10 ~ cp12 [Memo]
Ruby on Rails6 Guide pratique [Extensions] cp3 ~ cp6 [Mémo]
Ruby on Rails6 Guide pratique cp13 ~ cp15 [Mémo]
Ruby on Rails6 Guide pratique cp7 ~ cp9 [Mémo]
Ruby on Rails6 Guide pratique cp4 ~ cp6 [Mémo]
Ruby on Rails6 Guide pratique cp10 ~ cp12 [Memo]
Ruby on Rails6 Guide pratique cp16 ~ cp18 [Mémo]
Mémo de construction de l'environnement Ruby on Rails 6.0
[Ruby on Rails] Mémo d'introduction Select2 pour Webpacker
[Note personnelle] Construction de l'environnement Ruby on Rails (Windows)
Ruby on Rails élémentaire
Principes de base de Ruby on Rails
Association Ruby On Rails
Ruby on Rails5 Guide pratique d'apprentissage rapide 5.2 Chapitre 2 compatible
Ruby on Rails5 Guide pratique d'apprentissage rapide 5.2 Chapitre compatible3
Record d'apprentissage de Ruby on rails -2020.10.03
Création de portfolio Ruby on Rails
Record d'apprentissage Ruby on rails -2020.10.04
[Ruby on Rails] Debuck (binding.pry)
Record d'apprentissage de Ruby on rails -2020.10.05
Record d'apprentissage de Ruby on rails -2020.10.09
Record d'apprentissage Ruby on rails-2020.10.07 ②
Record d'apprentissage Ruby on rails-2020.10.07 ①
Annuler la migration de Ruby on Rails
Record d'apprentissage de Ruby on rails -2020.10.06
Résumé de la validation Ruby on Rails
Mémorandum de base Ruby on Rails
Variables Ruby on Rails, résumé constant
Installation de Ruby + Rails sur Ubuntu 18.04 (rbenv)
[Ruby on Rails] Introduction de la fonction de pagination
Connaissance de base de Ruby on Rails
Progatez Ruby on Rails
Comment utiliser Ruby on Rails
Ruby on Rails compatible japonais-anglais i18n
(Ruby on Rails6) "Effacer" le contenu publié
[Ruby on Rails] Fonction de sortie CSV
[Ruby on Rails] Création de la page de confirmation
Ruby On Rails conçoit un conflit de routage
[Ruby on Rails] Implémentation de la fonction de commentaire
[Ruby on Rails] DM, fonction de chat
[Ruby on Rails] Méthode d'aide pratique
[Ruby on Rails] Arrêtez de "boucler jusqu'à ce que ..."
[Ruby on Rails] Introduction des données initiales
[Ruby on Rails] Création d'un formulaire de demande
[Ruby on Rails] Afficher le test avec RSpec
[Ruby on Rails] Vérification du code à l'aide de Rubocop-airbnb
[Ruby on Rails] 1 modèle CRUD (routage principal)
Méthode d'installation de Ruby on Rails [édition Mac]
Modèle [Ruby on Rails], commande de terminal de contrôleur
Commande de création / suppression de modèle Ruby on Rails