__ ・ Implementieren Sie eine Funktion, mit der Sie Ihre eigenen Beiträge markieren können. __ __ __ ・ Implementieren Sie eine Funktion, mit der Sie die Suche anhand der an den Beitrag angehängten Tags eingrenzen können. __ __
·Umgebung Ruby 2.6-Serie Schienen 5.2 Serie
·Bibliothek Slim
__ ・ Rails-Anwendungsvorlage der oben genannten Umgebung __ Vorgehensweise zum Einrichten der Rails-Anwendung und zum Installieren von devise and Slim
__ ↓ Abgeschlossenes Bild ↓ __
- Benutzer: Beitrag
= Benutzer hat viele Beiträge für jede Person, daher gibt es eine Beziehung von 1 zu vielen.
- Post: Tag
= `Ein Post hat viele Tags
, `Ein Tag hat auch viele Posts
, also``` Viele-zu-viele-Beziehung. → Eine Zwischentabelle ist aufgrund der Viele-zu-Viele-Beziehung = ``
TagMap``` erforderlich
→ Eine Zwischentabelle ist eine Tabelle, in der nur die externen Schlüssel (post_id und tag_id) der "Many-to-Many-Tabelle (in diesem Fall Post- und Tag-Tabelle)" gespeichert werden und die Tabellen des jeweils anderen nur mit dem externen Schlüssel verwaltet werden. Mach es möglich.
$ rails g devise User //Erstellen Sie ein Benutzermodell aus dem Gerät $ rails g migration add_columns_to_users name:string //Namensspalte hinzugefügt $ rails g model Post content:string user:references //Postmodellerstellung $ rails g model Tag tag_name:string //Tag-Modellerstellung $ rails g model TagMap post:references tag:references //TagMap-Modellerstellung
>> - Da Spalten nicht zu dem von devise erstellten Benutzermodell hinzugefügt werden können, muss beim Hinzufügen einer Namensspalte diese als neue Migration hinzugefügt werden.
- <Tabellenname>: Für die in Referenzen angegebene Tabelle wird ein externer Schlüssel festgelegt. (Erforderlich)
### 3. Überprüfen Sie die erstellte Migrationsdatei
> #### 3-1.users Migrationsdatei
>>```db/migrate/[timestamps]_create_devise_users.rb
class DeviseCreateUsers < ActiveRecord::Migration[5.2]
def change
create_table :users do |t|
## Database authenticatable
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
#<Kürzung>
end
end
3-2. Fügen Sie der Benutzertabelle eine Namensspalte hinzu
class AddUsernameToUsers < ActiveRecord::Migration[5.2] def change add_column :users, :name, :string end end
> #### 3-3.posts Migrationsdatei
>>```ruby:db/migrate/[timestamps]_create_posts.rb
class CreatePosts < ActiveRecord::Migration[5.2]
def change
create_table :posts do |t|
t.text :content
t.references :user, foreign_key: true
t.timestamps
end
end
end
3-4.tags Migrationsdatei
class CreatePostTags < ActiveRecord::Migration[5.2] def change create_table :post_tags do |t| t.string :tag_name t.timestamps end end end
> #### 3-5.tag_maps Migrationsdatei
>>```ruby:db/migrate/[timestamps]_create_tag_maps.rb
class CreatePostTagMaps < ActiveRecord::Migration[5.2]
def change
create_table :tag_maps do |t|
t.references :post, foreign_key: true
t.references :tag, foreign_key: true
t.timestamps
end
end
end
4-1. Benutzermodelldatei
class User < ApplicationRecord
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable has_many :posts, dependent: :destroy end
>> ・ `abhängige :: zerstören`: Eine Option, die an die übergeordnete Klasse angehängt werden kann, damit die untergeordnete Klasse gelöscht werden kann, wenn die übergeordnete Klasse gelöscht wird.
> #### 4-2. Modelldatei veröffentlichen
>>```ruby:app/models/user.rb
class Post < ApplicationRecord
belongs_to :user
has_many :tag_maps, dependent: :destroy
has_many :tags, through: :tag_maps
end
__ ・ Mit der Option `through wird die Tag-Tabelle über die Tabelle tag_maps zugeordnet. Auf diese Weise können Sie die mit Post verknüpften Tags mithilfe von "Post.tags" abrufen. Dies kann verwendet werden, wenn Sie das Tag an den Beitrag anhängen und es auf dem Bildschirm mit den Beitragsdetails anzeigen möchten. __ __
__ ・ Wenn Sie die Option through verwenden, müssen Sie sie zuerst der Zwischentabelle zuordnen. __ __
__- Durch Hinzufügen der abhängigen :: destroy-Option zur Zwischentabelle wird die Beziehung zwischen Post und Tag gleichzeitig mit dem Löschen von Post gelöscht. __ __
4-4.Tag Modelldatei
class Tag < ApplicationRecord has_many :tag_maps, dependent: :destroy, foreign_key: 'tag_id' has_many :posts, through: :tag_maps end
>> __` ・ Nach der Zuordnung zur Tabelle tag_maps wird sie über tag_maps` der Tabelle posts zugeordnet. Sie können die mit den Tags verknüpften Posts mit "Tag.posts" abrufen. Dies kann verwendet werden, wenn Sie nach Posts mit einem bestimmten Tag suchen möchten, z. B. "Sport". __ __
> #### 4-5. TagMap-Modelldatei
>>```ruby:app/models/tag_map.rub
class PostTagMap < ApplicationRecord
belongs_to :post
belongs_to :tag
validates :post_id, presence: true
validates :tag_id, presence: true
end
__ ・ Da es mehreren Posts und mehreren Tags gehört, ist es miteins_zu verknüpft. __ __
__ ・ Wenn Sie die Beziehung zwischen Post und Tag aufbauen, müssen unbedingt zwei externe Schlüssel vorhanden sein. Überprüfen Sie diese. __ __
Rails.application.routes.draw do devise_for :users root to: 'posts#index' resources :posts end
>> __ ・ Legen Sie zu diesem Zeitpunkt vorerst das von devise bereitgestellte Routing, den Stammpfad und den Pfad zur Beitragsressource fest. __ __
## Implementieren Sie zunächst die Funktion, mit der Beiträge markiert werden können
### 6. Erstellen Sie einen Controller
> #### 6-1. Schreiben Sie den Code zum Erstellen von Posts und Tags in die Erstellungsaktion des Posts-Controllers.
>>```ruby:app/controllers/posts_controller.rb
class PostsController < ApplicationController
def create
@post = current_user.posts.new(post_params)
tag_list = params[:post][:tag_name].split(nil)
if @post.save
@post.save_tag(tag_list)
redirect_back(fallback_location: root_path)
else
redirect_back(fallback_location: root_path)
end
end
private
def post_params
params.require(:post).permit(:content)
end
end
__ Lassen Sie uns den obigen Code aufschlüsseln. __ __
@post = current_user.posts.new(post_params)
>> __ · Durch Festlegen von `current_user.posts` wird die ID des angemeldeten Benutzers in der user_id der posts-Tabelle gespeichert. Wenn jedoch` User und Post nicht zugeordnet sind, tritt ein Fehler auf. Masu`. Starke Parameter werden als Argument verwendet. __ __
>>```ruby:Holen Sie sich die Tags, die gesendet wurden
tag_list = params[:post][:tag_name].split(nil)
__ ・
params [: post] [: tag_name]
: Verweisen Sie im Formular auf das @ post-Objekt und senden Sie den Tag-Namen zusammen. Erhalten Sie ihn also in diesem Formular. Zum Beispiel wird es wie "Sport", "Studium", "Arbeit" gesendet. __ __
__ ・
.split (nil)
: Ordnen Sie die gesendeten Werte durch Leerzeichen getrennt an. Im obigen Beispiel fühlt es sich an wie ["Sport" "Studium" "Arbeit"]. Der Grund für das Anordnen ist, dass beim späteren Speichern dieses Werts in der Datenbank dieser nacheinander durch iterative Verarbeitung abgerufen werden muss. __ __
@post.save_tag(tag_list)
__ ・ `Prozess zum Speichern des zuvor in der Datenbank erfassten Arrays von Tags`. Die Definition von save_tag, die die Verarbeitung ausführt, wird später beschrieben. __ __
> #### 6-2. Schreiben Sie den Code, um den Beitrag und das Tag in der Indexaktion abzurufen.
>>```ruby:app/controllers/posts_controller.rb
def index
@tag_list = Tag.all #Lassen Sie alle die Tag-Liste in der Ansicht anzeigen.
@posts = Post.all #Holen Sie sich alle, um die Post-Liste in der Ansicht anzuzeigen.
@post = current_user.posts.new #Formular anzeigen_Wird für Modell mit verwendet.
end
def show @post = Post.find(params[:id]) #Holen Sie sich den Beitrag, auf den Sie geklickt haben. @post_tags = @post.tags #Holen Sie sich das Tag, das dem angeklickten Beitrag zugeordnet ist. end
### 7. Definieren Sie die Instanzmethode save_tag in der Post-Modelldatei.
> __ ・ Definieren Sie den Inhalt der Instanzmethode save_tag, die weiter oben in der Aktion create beschrieben wurde. __ __
>```ruby:app/models/post.rb
class Post < ApplicationRecord
#<Kürzung>
def save_tag(sent_tags)
current_tags = self.tags.pluck(:tag_name) unless self.tags.nil?
old_tags = current_tags - sent_tags
new_tags = sent_tags - current_tags
old_tags.each do |old|
self.post_tags.delete PostTag.find_by(post_tag_name: old)
end
new_tags.each do |new|
new_post_tag = PostTag.find_or_create_by(post_tag_name: new)
self.post_tags << new_post_tag
end
end
end
current_tags = self.tags.pluck(:tag_name) unless self.tags.nil?
> __ ・ Wenn mit @post ein Tag verknüpft ist, das zuvor durch die Erstellungsaktion gespeichert wurde, rufen Sie alle "Tag-Namen als Array" ab. __ __
>```ruby:Holen Sie sich alte Tags
old_tags = current_tags - sent_tags
__ ・ Alte_Tags sind die Tags, die im aktuell erfassten @post vorhanden sind, mit Ausnahme der gesendeten Tags. __ __
new_tags = sent_tags - current_tags
> __ ・ New_tags sind die Tags, die gesendet werden, mit Ausnahme der derzeit vorhandenen Tags. __ __
>```ruby:Alte Tags löschen
old_tags.each do |old|
self.tags.delete Tag.find_by(tag_name: old)
end
__- Alte Tags löschen. __ __
new_tags.each do |new| new_post_tag = Tag.find_or_create_by(tag_name: new) self.post_tags << new_post_tag end
> __- Speichern Sie das neue Tag in der Datenbank. __ __
> __ ・ Der Grund, warum es Zeit braucht, alte und neue Tags wie oben beschrieben zu erfassen und zu löschen, anstatt nur Tags einzeln zu erfassen und zu speichern, ist beispielsweise beim Bearbeiten eines Beitrags. Weil es funktionieren muss.
Es tut mir jedoch leid, diesmal werde ich die Implementierung der Bearbeitungsfunktion weglassen. __ __
### 8. Erstellen Sie eine Ansicht.
> #### 8-1. Erstellen Sie eine Ansicht der Beitragsliste.
>>```ruby:app/views/posts/index.html.slim
h3-Tag-Liste
- @tag_list.each do |list|
span
= link_to list.tag_name, tag_posts_path(tag_id: list.id)
= "(#{list.posts.count})"
hr
h3 post
= form_with(model: @post, url: posts_path, local: true) do |f|
= f.text_area :content
br
= "Sie können mehrere Tags hinzufügen, indem Sie ein Leerzeichen eingeben."
= "Beispiel: Musik, Literatursport"
= f.text_field :tag_name
br
= f.submit
hr
h3 Beitragsliste
- @posts.each do |post|
= link_to post.content, post
Lassen Sie uns den obigen Code aufschlüsseln.
>> __ ・ Zeigt alle von der Indexaktion erfassten Tags an und enthält außerdem einen Link zum Pfad zum Anzeigen von Posts, die sich auf dieses Tag beziehen. Klicken Sie auf diesen Link, um die mit diesem "Tag" verknüpften Beiträge anzuzeigen. Das Festlegen des Routings zum Abrufen dieses Links und das Erstellen der Aktion wird später beschrieben. __ __
>> __ ・ `" (# {list.posts.count}) "` zählt und zeigt an, wie viele Beiträge derzeit dieses Tag haben. __ __
>>```ruby:Neues Postformular (kann markiert werden)
= form_with(model: @post, url: posts_path, local: true) do |f|
= f.text_area :content
br
= "Sie können mehrere Tags hinzufügen, indem Sie ein Leerzeichen eingeben."
= "Beispiel: Musik, Literatursport"
= f.text_field :tag_name
br
= f.submit
__ ・
= f.text_field: tag_name
: Durch Schreiben dieser Zeile werden die im Formular eingegebenen Tags als Parameter params [: post] [: tag_name] an die Aktion create gesendet. .. __ __
8-2. Erstellen Sie eine Ansicht der Post-Detailseite.
h1 post details p= @post.content br = "Etikett: "
>> __ ・ Der Teil, der das Tag anzeigt, entspricht der in der Listenanzeige beschriebenen Methode. In diesem Fall unterscheidet sich der Teil "Tag, der einem bestimmten Beitrag zugeordnet ist". __ __
__ · Damit ist die Implementierung der Funktion abgeschlossen, mit der Sie Beiträge markieren können. __ __
## Implementieren Sie eine Funktion zum Eingrenzen und Anzeigen von Posts nach Tags
### 1. Routing hinzufügen.
>```ruby:config/routes.rb
Rails.application.routes.draw do
devise_for :users
root to: 'posts#index'
resources :posts
#Weiterleiten an Aktionen zum Anzeigen von Posts, die nach Tags gefiltert wurden
resources :tags do
get 'posts', to: 'posts#search'
end
end
__ ・ Durch Verschachteln können Sie den Pfad verwenden, um zur Postseite zu wechseln, die einem bestimmten Tag mit dem Namen "tag_posts_path (tag_id: tag.id)" zugeordnet ist, wie zuvor beschrieben. __ __
def search @tag_list = Tag.all #Holen Sie sich alle Tags, um alle Tags auf dieser Post-List-Anzeigeseite anzuzeigen @tag = Tag.find(params[:tag_id]) #Holen Sie sich das angeklickte Tag @posts = @tag.posts.all #Alle Beiträge anzeigen, die dem angeklickten Tag zugeordnet sind end
### 3. Erstellen Sie eine Seitenansicht, in der eine Liste von Posts angezeigt wird, die durch Tags eingegrenzt sind.
> __ ・ Erstellen Sie zunächst eine Datei search.html.slim im Verzeichnis app / views / posts. __ __
>```ruby:app/views/posts/search.html.slim
h2 post liste
#Tag-Liste
- @tag_list.each do |list|
span
= link_to list.tag_name, tag_posts_path(post_tag_id: list.id)
= "(#{list.posts.count})"
br
#Beitragsliste nach Tag eingegrenzt
= "Das Tag ist ─"
strong= "#{@tag.tag_name}"
= "─ Beitragsliste"
br
- @posts.each do |post|
= link_to post.content, post
br
= link_to 'Zuhause', root_path
__ ・ Der Tag-Listen-Teil ist der gleiche wie der Index-Teil. __ __
= "Das Tag ist ─" strong= "#{@tag.tag_name}" = "─ Beitragsliste"
> __ ・ In diesem Teil wird das entsprechende Tag angezeigt, damit Sie sehen können, welche Art von Tag eingegrenzt wurde. __ __
__ · Damit ist die Implementierung der Funktion zum Anzeigen von durch Tags eingegrenzten Posts abgeschlossen. Wie Sie sehen können, gibt es einige Überlappungen in der Ansicht. Wenn Sie diese Teile also partialisieren und umgestalten, sieht die Ansicht sauberer und besser aus. __ __
## Artikel, der sehr hilfreich war
[Hinweise zur Implementierung der Tag-Funktion in Rails ohne Verwendung von gem](https://qiita.com/tobita0000/items/daaf015fb98fb918b6b8)
Recommended Posts