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.
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]
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.
raise ActionController::BadRequest unless request.xhr?
xhr? Détermine si la demande provient d'Ajax.
= 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.
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é.
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```.
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.
La création de balises à l'aide de Tag-it est omise.
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.
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.
Si ces deux conditions sont remplies, les conditions pour la même condition de course seront remplies.
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.
Recommended Posts