Ruby on Rails6 Praktischer Leitfaden [Erweiterungen] cp10 ~ cp12 [Memo]

Einführung

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.

Überblick

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]

Funktionserweiterung Kapitel 10 Ajax

Gibt Text als Antwort zurück

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.


Alle außer Ajax-Anfragen ablehnen

raise ActionController::BadRequest unless request.xhr?

xhr? Bestimmt, ob die Anforderung von Ajax stammt.

Funktionserweiterung Kapitel 11 Baumstruktur

Zeigen Sie die ausgelassene Zeichenfolge an

= 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.


Nachrichtenbaum anzeigen

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.


Leistungsverbesserung

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```.

Modell-

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.

Funktionserweiterung Kapitel 12 Tagging

Die Tag-Erstellung mit Tag-it entfällt.

Erstellen Sie eine Tabelle zur exklusiven Steuerung

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.

Verwenden Sie 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

Es verhindert Tag-Konflikte, indem exklusive Sperren für die Datensätze in der Tabelle hash_locks erworben werden.

Zeitpunkt für die Verwendung von HashLock

Wenn diese beiden Bedingungen erfüllt sind, sind die Bedingungen für dieselbe Rennbedingung erfüllt.

Impressionen

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.

Quelle zitieren

Recommended Posts

Ruby on Rails6 Praktischer Leitfaden [Erweiterungen] cp7 ~ cp9 [Memo]
Ruby on Rails6 Praktischer Leitfaden [Erweiterungen] cp10 ~ cp12 [Memo]
Ruby on Rails6 Praktischer Leitfaden [Erweiterungen] cp3 ~ cp6 [Memo]
Ruby on Rails6 Praktischer Leitfaden cp13 ~ cp15 [Memo]
Ruby on Rails6 Praktischer Leitfaden cp7 ~ cp9 [Memo]
Ruby on Rails6 Praktischer Leitfaden cp4 ~ cp6 [Memo]
Ruby on Rails6 Praktischer Leitfaden cp10 ~ cp12 [Memo]
Ruby on Rails6 Praktischer Leitfaden cp16 ~ cp18 [Memo]
Ruby on Rails 6.0-Umgebungskonstruktionsnotiz
[Ruby on Rails] Select2-Einführungsnotiz für Webpacker
[Persönliches Memo] Ruby on Rails-Umgebungskonstruktion (Windows)
Ruby on Rails Elementary
Ruby on Rails Grundlagen
Ruby On Rails Association
Ruby on Rails5 - Schnellübungshandbuch 5.2 Kompatibel Kapitel2
Ruby on Rails5 - Schnellübungshandbuch 5.2 Kompatibel Kapitel3
Ruby on Rails Lernrekord -2020.10.03
Portfolioerstellung Ruby on Rails
Ruby on Rails Lernrekord -2020.10.04
[Ruby on Rails] Debuck (bindend.pry)
Ruby on Rails Lernrekord -2020.10.05
Ruby on Rails Lernrekord -2020.10.09
Ruby on Rails lernen Rekord-2020.10.07 ②
Ruby on Rails lernen Rekord-2020.10.07 ①
Brechen Sie die Ruby on Rails-Migration ab
Ruby on Rails Lernrekord -2020.10.06
Zusammenfassung der Ruby on Rails-Validierung
Ruby on Rails Grundlegendes Memorandum
Ruby on Rails-Variablen, konstante Zusammenfassung
Installation von Ruby + Rails unter Ubuntu 18.04 (rbenv)
[Ruby on Rails] Paging-Funktion eingeführt
Grundkenntnisse in Ruby on Rails
Progate Ruby on Rails5 Rückblick
Verwendung von Ruby on Rails
Ruby on Rails Japanisch-Englisch kompatibler i18n
(Ruby on Rails6) Gepostete Inhalte "löschen"
[Ruby on Rails] CSV-Ausgabefunktion
[Ruby on Rails] Erstellung der Bestätigungsseite
Ruby On Rails entwickelt Routing-Konflikte
[Ruby on Rails] Implementierung der Kommentarfunktion
[Ruby on Rails] DM, Chat-Funktion
[Ruby on Rails] Praktische Hilfsmethode
[Ruby on Rails] Stoppen Sie "Looping bis ..."
[Ruby on Rails] Einführung der Anfangsdaten
[Ruby on Rails] Erstellen eines Anfrageformulars
[Ruby on Rails] Test mit RSpec anzeigen
[Ruby on Rails] Codeprüfung mit Rubocop-Airbnb
[Ruby on Rails] 1 Modell CRUD (Routing Main)
Ruby on Rails-Installationsmethode [Mac Edition]
Modell [Ruby on Rails], Befehl für Controller-Terminal
Befehl zum Erstellen / Löschen von Ruby on Rails-Modellen