Je fréquente actuellement une école de programmation appelée DMM WEB CAMP Comme utilisé sur Instagram et Twitter pour le portfolio, qui est le problème du troisième mois Implémentation d'une balise de hachage. J'espère qu'il sera utile pour ceux qui le mettront en œuvre à l'avenir.
Implémenter des balises de hachage dans des légendes de type insta créées avec des rails https://qiita.com/goppy001/items/791c946abdb41c9495bb
Le flux général est le même que celui du site ci-dessus, mais les parties qui ne fonctionnaient pas bien ont été modifiées.
Tableau de poste
Au départ, c'était une structure de table avec seulement body et user_id, mais nous avons ajouté une colonne hashbody pour entrer des balises de hachage. À propos, l'image est enregistrée dans une autre table en raison des spécifications du portfolio, mais il n'y a pas de problème même si la colonne image est dans cette table.
$rails g model Hashtag hashname:string
Créez un modèle pour stocker les balises de hachage. Le hashtag est stocké dans la colonne hashname.
create_hashtags.rb
class CreateHashtags < ActiveRecord::Migration[5.2]
def change
create_table :hashtags do |t|
t.string :hashname
t.timestamps
end
add_index :hashtags, :hashname, unique: true
end
end
$ rails g model HashtagPostImage post_image:references hashtag:references
Une table intermédiaire entre la table Hashtag et la table PostImage. Les commandes ici sont légèrement différentes dans l'article auquel j'ai fait référence. Puisqu'il s'agit d'une table intermédiaire, elle apporte le hashtag et l'identifiant de postimage en tant que clés externes. Puisqu'il s'agit d'un type de références, si vous saisissez hashtag_id au moment de la création Veuillez noter que le nom de colonne complété sera hashtag_id_id.
create_hashtag_post_images.rb
class CreateHashtagPostImages < ActiveRecord::Migration[5.2]
def change
create_table :hashtag_post_images do |t|
t.references :post_image, foreign_key: true
t.references :hashtag, foreign_key: true
end
end
end
Mon grand
$ rails db:migrate
hashtag.rb
class Hashtag < ApplicationRecord
validates :hashname, presence: true, length: { maximum: 50 }
has_many :hashtag_post_images, dependent: :destroy
has_many :post_images, through: :hashtag_post_images
end
Pour le moment, j'ai fixé la limite supérieure à 50 caractères.
hashtag_post_image.rb
class HashtagPostImage < ApplicationRecord
belongs_to :post_image
belongs_to :hashtag
validates :post_image_id, presence: true
validates :hashtag_id, presence: true
end
post_image.rb
class PostImage < ApplicationRecord
has_many :hashtag_post_images, dependent: :destroy
has_many :hashtags, through: :hashtag_post_images
end
post_image.rb
after_create do
post_image = PostImage.find_by(id: id)
#Détecte les balises de hachage saisies dans hashbody
hashtags = hashbody.scan(/[##][\w\p{Han}Ah-Gae-゚]+/)
hashtags.uniq.map do |hashtag|
#La balise de hachage est au début#Enregistrer après avoir supprimé
tag = Hashtag.find_or_create_by(hashname: hashtag.downcase.delete('#'))
post_image.hashtags << tag
end
end
#Mettre à jour l'action
before_update do
post_image = PostImage.find_by(id: id)
post_image.hashtags.clear
hashtags = hashbody.scan(/[##][\w\p{Han}Ah-Gae-゚]+/)
hashtags.uniq.map do |hashtag|
tag = Hashtag.find_or_create_by(hashname: hashtag.downcase.delete('#'))
post_image.hashtags << tag
end
end
Il est marqué de manière à ce que cette action soit effectuée lors de la création et de la mise à jour.
・ Post_image = PostImage.find_by (id: id) Vous permet de trouver le message que vous avez créé.
・ Hashtags = hashbody.scan (/ [# #] [\ w \ p {Han} a-ga- ゚] + /) Ici, recherchez la balise de hachage entrée et la valeur d'entrée avec [# #] au début. hashbody est le nom de colonne de ma base de données, donc cela dépend de l'application. N'importe quelle colonne pour l'entrée de texte dans la table de publication fera l'affaire.
・ Hashtags.uniq.map do |hashtag|
tag = Hashtag.find_or_create_by(hashname: hashtag.downcase.delete('#'))
post_image.hashtags << tag
end
En répétant avec map, plusieurs balises de hachage sont enregistrées dans la postimage.
・ Post_image.hashtags.clear Au moment de la mise à jour, il semble que la balise de hachage soit supprimée une fois.
routes.rb
get '/post_image/hashtag/:name' => 'post_images#hashtag'
get '/post_image/hashtag' => 'post_images#hashtag'
Dans mon cas, je voulais créer une page de liste de balises de hachage, j'ai donc préparé deux itinéraires.
post_images_helper.rb
module PostImagesHelper
def render_with_hashtags(hashbody)
hashbody.gsub(/[##][\w\p{Han}Ah-Gae-゚]+/) { |word| link_to word, "/post_image/hashtag/#{word.delete("#")}",data: {"turbolinks" => false} }.html_safe
end
end
link_to word, "/post_image/hashtag/#{word.delete("#")}" L'URL ici dépend du contenu de l'application. Cela signifie que cliquer sur la balise de hachage vous amènera à l'URL ici. Tapez l'url que vous avez écrite dans route plus tôt.
controllers/post_images_controller.rb
class PostImagesController < ApplicationController
def new
@postimagenew = PostImage.new
@postimagenew.post_image_images.new
end
def create
@postimagenew = PostImage.new(post_image_params)
@postimagenew.user_id = current_user.id
if @postimagenew.save
redirect_to post_images_path
else
render('post_images/new')
end
end
def destroy
@postimage = PostImage.find(params[:id])
@postimage.destroy
redirect_to post_images_path
end
private
def post_image_params
params.require(:post_image).permit(:body, :hashbody, :user_id, post_image_images_images: [], hashtag_ids: [])
end
Ne vous inquiétez pas de post_image_images_images: [] pour enregistrer les images dans les paramètres forts sous forme de tableau dans une autre table. hashtag_ids est entré car plusieurs balises de hachage sont enregistrées lors de la création de PostImage.
View
views/post_images/new.html.erb
<div class= "row">
<div class="col-lg-2 col-md-2">
</div>
<div class="col-xs-12 col-lg-8 col-md-8 col-sm-12">
<div class= "postimage-new-box">
<% if @postimagenew.errors.any? %>
<div id="error_explanation">
<h3><%= @postimagenew.errors.count %>Impossible de publier en raison d'une erreur de saisie</h3>
<ul>
<% @postimagenew.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<h3>Nouveau poste</h3>
<div class="previw">
</div>
<%= form_with model:@postimagenew, local: true do |f| %>
<div class="attachment-field">
<p>Sélectionnez une image (plusieurs peuvent être spécifiées)</p>
<%= f.attachment_field :post_image_images_images, multiple:true %>
</div>
<br>
<br>
<div class= "postimage-body-box">
<p>Veuillez saisir les détails du message</p>
<%= f.text_area :body, size:"55x12" %>
<br>
<p>Champ de saisie de balise de hachage</p>
<%= f.text_area :hashbody, size:"55x3" %>
<br>
<div class= "postimage-new">
<%= f.submit "Nouveau poste" ,class:'postimage-new-button' %>
</div>
<% end %>
</div>
</div>
</div>
<div class="col-lg-2 col-md-2">
</div>
</div>
Ce qui suit est écrit dans View.
ruby:post_images/show.html.erb
<%= render_with_hashtags(@postimage.hashbody) %>
Ce qui précède appelle la méthode créée précédemment avec helper. Au fait, le contrôleur pour post_images / show est ici.
controllers/post_images_controller.rb
def show
@postimage = PostImage.find(params[:id])
end
Je pense qu'il s'agit simplement de transmettre les informations dans le champ de saisie hashtag de @postimage à Hellber.
Lorsque vous cliquez dessus, cela ressemble à ceci.
post_images_controller.rb
def hashtag
@user = current_user
if params[:name].nil?
@hashtags = Hashtag.all.to_a.group_by{ |hashtag| hashtag.post_images.count}
else
@hashtag = Hashtag.find_by(hashname: params[:name])
@postimage = @hashtag.post_images.page(params[:page]).per(20).reverse_order
@hashtags = Hashtag.all.to_a.group_by{ |hashtag| hashtag.post_images.count}
end
end
La notation ici varie en fonction du site que vous créez. Je voulais créer une page où vous pouvez voir la liste des hashtags, donc dans le cas des paramètres [: name] .nil? Il existe une branche conditionnelle qui n'affiche pas post_image. De plus, bien qu'il s'agisse de group_by, les balises de hachage peuvent être affichées dans l'ordre du nombre de publications associées à la balise de hachage. C'est écrit comme ça.
post_images/hashtag.html.erb
<div class="row">
<% if params[:name] == nil %>
<% else %>
<div class= "col-xs-12 col-lg-12 col-md-12 col-sm-12">
<div class="hashtag-post-box">
<h3 class="search-title">#<%= @hashtag.hashname %>: <%= @postimage.count %>Cas</h3>
<div class="flex-box">
<% @postimage.each do |postimage| %>
<div class= "post-image-index-post-box">
<p class="index-post-box-top">
<%= postimage.created_at.strftime("%Y/%m/%d") %>
</p>
<span class='far fa-comments index-comment-count' id='comment-count_<%= postimage.id %>' style="color: #777777;">
<%= render 'post_image_comments/comment-count', postimage:postimage %>
</span>
<span id = "favorite-button_<%= postimage.id %>"class="post-box-top-favorite">
<%= render 'post_image_favorites/favorite',postimage: postimage %>
</span>
<%= link_to post_image_path(postimage),data: {"turbolinks" => false} do %>
<ul class="slider">
<% postimage.post_image_images.each do |post| %>
<li>
<%= attachment_image_tag post, :image ,size:'430x360', format:'jpg',class:"image" %>
</li>
<% end %>
</ul>
<% end %>
<p class="hashtag-post-box-name">
<%= link_to user_path(postimage.user) do %>
<%= attachment_image_tag postimage.user, :profile_image,size:'30x30', format:'jpg',fallback:'no_image.jpg',class:'min-image' %>
<span class="index-post-box-user"><%= postimage.user.name %>
</span>
<% end %>
</p>
<div class="image-show-body-hash" style="padding:2%">
<%= simple_format(postimage.body.truncate(50))%>
<% if postimage.body.length > 50 %>
<span class="text-prev"><%= link_to 'Lire la suite', post_image_path(postimage), data: {"turbolinks" => false} %>
</span>
<% end %>
</div>
</div>
<% end %>
</div>
</div>
<div class="image-index-pagination" data-turbolinks="false">
<%= paginate @postimage,class:"paginate" %>
</div>
</div>
<% end %>
</div>
<div class="row">
<div class= "col-xs-12 col-lg-12 col-md-12 col-sm-12">
<div class= "hashtag-name">
<% @hashtags.sort.reverse.each do |count| %>
<% count[1].each do |hashtag| %>
<p><%= link_to "##{hashtag.hashname} (#{hashtag.post_images.count})Cas","/post_image/hashtag/#{hashtag.hashname}",data: {"turbolinks" => false} %>
</p>
<% end %>
<% end %>
</div>
</div>
</div>
</div>
Je suis désolé d'avoir du mal à comprendre le nom de la classe et ainsi de suite. Les points importants sont les suivants.
post_images/hashtag.html.erb
<% if params[:name] == nil %>
<% else %>
<% end %>
Avec cette notation, le branchement conditionnel est effectué avec post_image / hashtag et post_image / hashtag /: name écrits dans route plus tôt. En écrivant le traitement lorsque les paramètres sont nuls dans chacun du contrôleur et de la vue, une erreur est évitée.
post_image/hashtag.html.erb
<div class= "hashtag-name">
<% @hashtags.sort.reverse.each do |count| %>
<% count[1].each do |hashtag| %>
<p><%= link_to "##{hashtag.hashname} (#{hashtag.post_images.count})Cas","/post_image/hashtag/#{hashtag.hashname}",data: {"turbolinks" => false} %>
</p>
<% end %>
<% end %>
</div>
La liste des balises de hachage s'affiche ici. L'affichage est affiché dans l'ordre décroissant des publications liées aux balises de hachage.
Si vous ne séparez pas le champ de saisie de la balise de hachage, la balise de hachage restera sous forme de phrase dans la description de l'article, je l'ai donc implémentée sous la forme de l'enregistrer dans une autre colonne. Le hashbody est intentionnellement caché là où le hashtag est affiché avec le message. C'est turbolinks false qui existe beaucoup sur la vue, mais js ne fonctionne pas bien et il est écrit, donc vous pouvez l'ignorer.
Je suis désolé s'il y a des parties difficiles à comprendre dans le premier post. J'espère que cela sera utile pour ceux qui créeront désormais un portfolio.
2020/7/1 Correction du fichier de migration de la table intermédiaire. Il y avait un phénomène qui ne pouvait pas être détruit si id False était défini, nous l'avons donc corrigé. En même temps, j'ai ajouté dependant :: destroy au modèle has_many.
Nous avons également ajouté un contrôleur et une vue pour le hashtag et la partie post-sauvegarde. Nous nous excusons pour tout inconvénient.
Recommended Posts