Der Autor dieses Artikels ist ein Anfänger, der gerade erst anfängt, Programmieren zu lernen. Ich würde mich freuen, wenn Sie auf Fehler hinweisen könnten.
Dieser Artikel ist eine persönliche Notiz von dem, was ich durch Lesen des Ruby on Rails 6 Practical Guide gelernt habe. Es scheint schwer zu lesen zu sein, da es auszugsweise und aufgegriffen ist. Entschuldigung. Dieses Buch hat auch eine Fortsetzung Erweiterung, und beide wurden zum Zeitpunkt des Schreibens des Artikels untersucht. Ich werde auch einen Artikel zur Überprüfung schreiben. Ich werde cp1 und cp2 der Funktionserweiterung überspringen, weil sie die Umgebungskonstruktion und den Code des Hauptteils erklären. Dieser Artikel ist der letzte.
Vorheriger Artikel Ruby on Rails6 - Praktischer Leitfaden cp4 ~ cp6 [Memo] Ruby on Rails6 - Praktischer Leitfaden cp7 ~ cp9 [Memo] Ruby on Rails6 - Praktischer Leitfaden cp10 ~ cp12 [Hinweis] Ruby on Rails6 - Praktischer Leitfaden cp13 ~ cp15 [Memo] Ruby on Rails6 - Praktischer Leitfaden cp16 ~ cp18 [Memo] Ruby on Rails6 - Praktischer Leitfaden [Erweiterungen] cp3 ~ cp5 [Memo] Ruby on Rails6 - Praktischer Leitfaden [Erweiterungen] cp7 ~ cp9 [Memo]
render plain: Message.unprocessed.count
Referenz: Rails Guide
JavaScript Es ist ein Programm, das die Anzahl neuer Anfragen jede Minute überprüft und aktualisiert.
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)
})
Der $ .get-Methodenteil von JQuery wird im folgenden Muster geschrieben.
$.get(X, (data) => {
Y
})
.fail(Z)
Die URL der API, die mit Ajax auf X zugreift, und der Code, mit dem Y das Zugriffsergebnis erhält und ausführt. Die von der API zurückgegebenen Daten werden in den Argumentdaten gespeichert, und Sie können auf diesen Wert in Y verweisen. Wenn .fail (Z) angegeben ist, wird Z ausgeführt, wenn der Zugriff durch Ajax fehlschlägt.
window.setInterval ist eine Methode, die die im ersten Argument angegebene Funktion in regelmäßigen Abständen aufruft.
raise ActionController::BadRequest unless request.xhr?
xhr? Bestimmt, ob die Anforderung von Ajax stammt.
= truncate(content, length: 20)
Die Truncate-Methode lässt die an das Argument übergebene Zeichenfolge weg und zeigt sie an. Der Standardwert beträgt 30 Zeichen.
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 ist als rekursive Methode definiert. Sie rufen sich in einer Methode auf. Es wird nur das Thema des Hauptobjekts hervorgehoben, das auf dieser Seite angezeigt wird, und es werden Links aus den übergeordneten und untergeordneten Objekten generiert. Wir rufen expand für die Kinder dieses Objekts in der Reihenfolge von root auf. Infolgedessen wird HTML in der Reihenfolge von root generiert und der Baum wird dargestellt.
Der obige Code kann auch den Baum darstellen. Je tiefer die Struktur, desto öfter wird auf die Datenbank zugegriffen.
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
Eine Klasse für den Umgang mit baumstrukturierten Daten. Das erste Argument des Konstruktors ist das Stammobjekt, und das zweite Argument ist sein untergeordnetes Objekt.
Ich erstelle einen Hash `@ node``` mit allen zum Baum gehörenden Objekten als Werte. Jedes Objekt hat ein Array von untergeordneten Objekten
`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
Definiert child_nodes zum Verwalten von untergeordneten Objekten. In Nachrichten werden andere Objekte als root (Startpunkt) festgelegt, die zum Baum gehören. Ich erstelle ein SimpleTree-Objekt.
Schreiben Sie die Baummethode von MessagePresenter neu.
app/presenters/message_presenter.rb
def tree
expand(object.tree.root) #Veränderung
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| #Veränderung
m << expand(c)
end
end
end
end
Die Anzahl der Abfragen an die Datenbank wurde reduziert.
Die Tag-Erstellung mit Tag-it entfällt.
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
Erstellen Sie Saatgutdaten für die Produktion.
db/seeds/hash_locks.rb
256.times do |i|
HashLock.create!(table: "tags", column: "value", key: sprintf("%02x", i))
end
Die Zieltabelle wird im Tabellenattribut angegeben, und die Zielspalte wird im Spaltenattribut angegeben.
Der Schlüsselausdruck `sprintf ("% 02x ", i)`
gibt die zweistelligen Hexadezimalzahlen "00" als Zeichenfolge an "ff" zurück.
Fügen Sie der HashLock-Klasse eine Klassenmethode hinzu.
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
Die Digest :: MD5-Klassenmethode hexdigest generiert aus dem im Argument angegebenen Wert einen Hashwert und gibt ihn als 32-stellige Hexadezimalzahl zurück. Der gleiche Hashwert wird aus der gleichen Zeichenfolge generiert. Suchen Sie den Datensatz mit den ersten beiden Ziffern des generierten Hexadezimalschlüssels und erhalten Sie eine exklusive Sperre.
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
Es verhindert Tag-Konflikte, indem exklusive Sperren für die Datensätze in der Tabelle hash_locks erworben werden.
Wenn diese beiden Bedingungen erfüllt sind, sind die Bedingungen für dieselbe Rennbedingung erfüllt.
Die Gesamtzahl der beiden Bücher betrug ungefähr 850 Seiten, aber ich konnte das Rennen zwei Wochen lang ohne Kopieren beenden. Es war im Vergleich zum Rails-Tutorial überwältigend schwierig, aber ich verstehe die Erklärung nicht, wahrscheinlich aufgrund meiner Erfahrung mit der Entwicklung von App! Es ist nicht passiert und ich konnte weitermachen. Ich wurde weiter an meinen Mangel an Wissen erinnert. Für Anfänger ist es schwieriger, aber ich bin froh, dass ich es gelesen habe, weil es voller praktischem Know-how war. Ich werde weiter hart lernen.
Recommended Posts