Ich habe eine Tag-Suchfunktion in einer App implementiert, die ich gerade entwickle, daher werde ich sie hier als Memorandum zusammenfassen. Ich habe es nicht gewagt, Edelsteine zu verwenden, also konnte ich das Wesentliche verstehen.
【Umgebung】
Wenn Sie ein Tag in das neue Post-Formular eingeben, wird das eingegebene Tag in der Post-Liste und in der Seitenleiste angezeigt. Mit dieser Funktion können Sie die Beiträge mit diesem Tag eingrenzen, indem Sie auf das in der Seitenleiste angezeigte Tag klicken.
Geben Sie ein Tag aus dem Post-Formular ein
Das in ↑ eingegebene Tag wird in der Seitenleiste und in der Beitragsliste angezeigt Durch Klicken auf das in der Seitenleiste angezeigte Tag können Sie die Artikel eingrenzen, die dieses Tag enthalten. (Da dies ein Beispiel ist, nur ein Fall)
Ich gehe davon aus, dass das Artikelmodell und das Post-Modell bereits erstellt wurden. (Hier handelt es sich um ein Artikelmodell. Bitte ersetzen Sie es selbst.)
Erstellen Sie zunächst das Tag-Modell und das Tagmap-Modell wie gewohnt.
$ rails g model Tagmap item:references tag:references
$ rails g model tag tag_name:string
Da Tagmap dem Artikelmodell und dem Tag-Modell zugeordnet ist, werden Verweise an den Datentyp angehängt. Wenn Sie dies tun, wird Rails einen guten Job machen. Wenn Sie also mehr wissen möchten, gehen Sie bitte auf Google.
class CreateTagmaps < ActiveRecord::Migration[6.0]
def change
create_table :tagmaps do |t|
t.references :item, null: false, foreign_key: true
t.references :tag, null: false, foreign_key: true
t.timestamps
end
end
end
Dies ist indiziert.
class CreateTags < ActiveRecord::Migration[6.0]
def change
create_table :tags do |t|
t.string :tag_name, null: false
t.timestamps
end
add_index :tags, :tag_name, unique: true
end
end
Migrieren Sie dann wie gewohnt.
$ rails db:migrate
item.rb
has_many :tagmaps, dependent: :destroy
has_many :tags, through: :tagmaps
tag.rb
class Tag < ApplicationRecord
has_many :tagmaps, dependent: :destroy
has_many :items, through: :tagmaps
end
Tag ist auch mit Tagmaps verknüpft. ↑
Mit gründlich können Sie über Tagmaps auf Elemente zugreifen.
tagmap.rb
class Tagmap < ApplicationRecord
belongs_to :item
belongs_to :tag
end
↑ Rails beschreibt automatisch das zugehörige Teil im Referenzformular!
items_controller.rb
def index
if params[:search].present?
items = Item.items_serach(params[:search])
elsif params[:tag_id].present?
@tag = Tag.find(params[:tag_id])
items = @tag.items.order(created_at: :desc)
else
items = Item.all.order(created_at: :desc)
end
@tag_lists = Tag.all
@items = Kaminari.paginate_array(items).page(params[:page]).per(10)
end
Ich werde den Code hier erklären. Die Indexaktion verwendet die if-Anweisung, um die drei Muster zu trennen, und der der Elementvariablen zugewiesene Wert wird gemäß diesem Ergebnis geändert.
items_controller
def create
@item = Item.new(item_params)
tag_list = params[:item][:tag_name].split(nil)
@item.image.attach(params[:item][:image])
@item.user_id = current_user.id
if @item.save
@item.save_items(tag_list)
redirect_to items_path
else
flash.now[:alert] = 'Buchung fehlgeschlagen'
render 'new'
end
end
Der Punkt in der Erstellungsaktion des Elementcontrollers ist der Zuordnungsteil zur Variablen tag_list in der dritten Zeile. rubys ** String # split ** teilt den String durch das durch das erste Argument angegebene Trennzeichen (diesmal null) und gibt das Ergebnis als Array von Strings zurück. Wenn Sie einen Block angeben, wird der Block nicht zurückgegeben, sondern mit einer geteilten Zeichenfolge aufgerufen. Wenn Sie Tag-Daten senden, die durch ein 1-Byte-Leerzeichen '' vom Formular getrennt sind, werden sie nach dem Entfernen der führenden und nachfolgenden Leerzeichen durch eine leere Zeichenfolge getrennt. Dieses Mal werden wir dies verwenden.
Die vom neuen Postformular gesendeten Parameter werden durch ein Leerzeichen (Null) getrennt, angeordnet und mithilfe der in der Elementklasse definierten Methode ** save_items ** in der Datenbank gespeichert. (Bitten Sie den Benutzer, Tags in das durch Leerzeichen getrennte Formular einzugeben.)
item.rb
#Fuzzy-Suche nach Suchmethode, Titel und Inhalt
def self.items_serach(search)
Item.where(['title LIKE ? OR content LIKE ?', "%#{search}%", "%#{search}%"])
end
def save_items(tags)
current_tags = self.tags.pluck(:tag_name) unless self.tags.nil?
old_tags = current_tags - tags
new_tags = tags - current_tags
# Destroy
old_tags.each do |old_name|
self.tags.delete Tag.find_by(tag_name:old_name)
end
# Create
new_tags.each do |new_name|
item_tag = Tag.find_or_create_by(tag_name:new_name)
self.tags << item_tag
end
end
↑ Wenn beim Speichern von Tag-Daten unter den vom Formular gesendeten Tag-Daten bereits ein Tag-Name vorhanden ist, verwenden Sie die Zupfmethode aus der Spalte tag_name der Tags-Tabelle, um alle Daten einmal abzurufen und auf current_tags zu setzen. Ersatz. (Wenn alles neu ist, ist es gleich Null.) Sie können alte Tags (old_tags) definieren, indem Sie das vom Controller übergebene Array von Tags als Argument von current_tags subtrahieren. Hierbei handelt es sich um einen Satz bereits vorhandener Tag-Daten. Dies liegt daran, dass Ruby gemeinsame Elemente durch Subtrahieren eines Arrays extrahieren kann.
** Konkretes Beispiel: **
tags(tag_list = params[:item][:tag_name].split(nil)Anordnung, die vom Controller kommt) = ["Rails" "ruby" "React"]
current_tags(Tag-Daten, die derzeit in der Datenbank vorhanden sind) = ["Rails" "ruby" "Vue.js"]
old_tags = ["Rails" "ruby" "Vue.js" "Docker"] - ["Rails" "ruby" "React"]
old_tags = ["Rails" "ruby"]
↑ Das gemeinsame Element der beiden Arrays bleibt erhalten (alte bereits vorhandene Tags können berechnet werden)
** Auszug aus der Beschreibung des neuen Beitragsformulars (UIkit wird für das CSS-Framework verwendet) **
.uk-form.new_post_form
= form_with(model: [@tag,@item], local: true) do |f|
.uk-margin-small
= f.text_field :title, placeholder: "Geben Sie einen Titel ein (bis zu 35 Zeichen)", class: 'uk-input'
.uk-margin-small
= f.text_field :tag_name, placeholder: "Geben Sie bis zu 5 Tags ein, die sich auf Programmiertechnologie und Rekrutierungsanforderungen beziehen und durch Leerzeichen getrennt sind(Beispiel Ruby Rails)", class: 'uk-input uk-form-small'
** Teilausschnitt aus der Seitenleiste **
haml:index.html.haml
%li.search_friend_by_categorize
.uk-text-secondary.uk-text-bold
Suche nach Tag
%ul.uk-flex.uk-flex-wrap
- @tag_lists.each do |list|
%li
= link_to list.tag_name, items_path(tag_id: list.id), class: 'tag_list'
Anzeigen von Tags in einer Liste der veröffentlichten Artikel
haml:index.html.haml
%p.tag_list_box
- item.tags.each do |tag|
= link_to "##{tag.tag_name}", items_path(tag), class: 'smaller tag_list'
Die Ansicht sieht so aus. Es ist nicht besonders schwierig!
Ich habe es in Eile geschrieben, daher kann es zu Fehlern kommen. Wenn Sie Anregungen oder Eindrücke haben, würde ich mich freuen, wenn Sie einen Kommentar abgeben könnten! !!