[RUBY] [Rails] Utilisez la zone déroulante pour trier la liste des articles par date ou par nombre de likes.

Au début

Je voulais une fonction pour trier les messages par date et heure et le nombre de likes dans l'application d'origine, j'ai donc réussi à l'implémenter tout en étant assez accro, je vais donc le laisser comme un mémorandum.

supposition

__ ● Environnement __ ・ Série Ruby 2.6 ・ Série Rails 5.2 __ ● Bibliothèque utilisée __ · Svelte · Concevoir __ ● La fonction Like est implémentée __ ・ [Rails] Implementation of Like Function (Slim et le dispositif sont également présentés dans cet article)

↓ Cela ressemble à ceci après le montage ↓

(Je suis désolé, ça n'a pas l'air bien ...) ezgif.com-video-to-gif.gif

la mise en oeuvre

1. Commencez par créer un formulaire déroulant

Liste des messages h1   = form_with model: @post, url: search_path, method: :get, local: true do |form| = form.select :keyword, [ ['Les messages sont les plus récents', 'new'], ['Messages les plus anciens', 'old'], ['Par ordre décroissant de likes', 'likes'], ['Dans l'ordre croissant des likes', 'dislikes'], ] = form.submit   #================La partie qui a été implémentée à l'origine========================



 >> __ ・ Décomposons ce qui se passe. __

>>```ruby
= form_with model: @post, url: search_path, 
            method: :get, local: true do |form|

__ · Post model'' est spécifié comme modèle à utiliser dans le formulaire. Cela enverra les données avec la valeurparams [: post]`. __

__ ・ Après la recherche, nous préparerons une page pour afficher les résultats de la recherche, alors définissez le chemin sur search_path``` et envoyez-le en tant que requête GET. __

__ ・ local: vrai```. Si cela n'est pas spécifié dans form_with, cela est considéré comme une communication Ajax. Si vous n'utilisez pas JS, vous devez l'ajouter sinon il ne sera pas rendu. __

= form.select :keyword, [ ['Les messages sont les plus récents', 'new'], ['Messages les plus anciens', 'old'], ['Par ordre décroissant de likes', 'likes'], ['Dans l'ordre croissant des likes', 'dislikes'], ] = form.submit



 >> __ ・ Vous pouvez créer un formulaire déroulant en utilisant la méthode de sélection.
 L'utilisation est comme `` `select (" object "," method "," choice ")` ``. __

 >> __ ・ `` `` Le premier argument object``` correspond au `` `` post object` '' ``, mais omettez-le lorsque vous utilisez form_with. __

 >> __ ・ `` `` La méthode du second argument``` est une `` chose qui est envoyée en tant que paramètre au contrôleur` `, alors veuillez la décrire librement. __
 __ Dans ce cas, puisque le mot-clé est spécifié, il sera envoyé sous la forme `` `` params [: mot-clé] `` ``. __

 >> __ ・ Dans la partie choice```, qui est le troisième argument,
 ```[ [Valeur à afficher par le menu déroulant 1,Paramètres envoyés à l'action], 
 [Valeur à afficher dans la partie déroulante 2,Paramètres envoyés à l'action], 
 [Valeur à afficher dans le menu déroulant, Partie 1, Paramètres envoyés à l'action]] Spécifiez `` `. __

### 2. Modifiez le routage

>```ruby:config/routes.rb
Rails.application.routes.draw do
#================La partie qui a été implémentée à l'origine========================
  devise_for :users
  resources :users
 
  root to: 'posts#index'
  resources :posts, only: [:index, :new, :create, :show, :edit, :update] do
    resource :favorites, only: [:create, :destroy]
  end
#================La partie qui a été implémentée à l'origine========================
 
  #Envoyer les résultats de la recherche à l'action de recherche du contrôleur de messages
+ get 'search' => 'posts#search'
 
end

3. Modifier le contrôleur de messages

class PostsController < ApplicationController . . . def search selection = params[:keyword] @posts = Post.sort(selection) end . . . end


 >> __ ・ Créez une action de recherche. Dans les paramètres [: mot-clé], la valeur sélectionnée dans le formulaire de tri est reçue et stockée dans une variable locale appelée sélection. __
 
 >> __ · `sort` est une méthode d'instance pour Post, après quoi elle est définie dans la classe de modèle Post afin que les publications soient récupérées dans l'ordre dans lequel elles sont triées en fonction de la valeur de sélection. __

### 4. Définissez la méthode d'instance de tri dans le modèle Post.

>```ruby:app/models/user.rb
class Post < ApplicationRecord
  .
  .
  .
  def self.sort(selection)
    case selection
    when 'new'
      return all.order(created_at: :DESC)
    when 'old'
      return all.order(created_at: :ASC)
    when 'likes'
      return find(Favorite.group(:post_id).order(Arel.sql('count(post_id) desc')).pluck(:post_id))
    when 'dislikes'
      return find(Favorite.group(:post_id).order(Arel.sql('count(post_id) asc')).pluck(:post_id))
    end
  end
  .
  .
  .
end

__ ・ Puisqu'il s'agit d'une définition de méthode d'instance, self est ajouté. __

__ ・ L'instruction case définit les conditions de tri en fonction de la valeur passée à la sélection. __

__ ↓ Trier par date __

when 'new' return all.order(created_at: :DESC) when 'old' return all.order(created_at: :ASC)


 >> __ ↓ Trier par nombre de likes __

>>```ruby
when 'likes'
   return find(Favorite.group(:post_id).order(Arel.sql('count(post_id) desc')).pluck(:post_id))
when 'dislikes'
   return find(Favorite.group(:post_id).order(Arel.sql('count(post_id) asc')).pluck(:post_id))

__ ・ Dans Favorite.group (: post_id), post_id regroupe les mêmes messages. __

__ · order (Arel.sql ('count (post_id) desc')), compter combien de user_ids sont stockés dans les articles groupés et trier à partir du plus (c'est-à-dire combien) Je compte si c'est aimé). __ __ʻArel.sql () est une contre-mesure d'injection SQL`. __

__ ・ Dans pluck (: post_id), post_id lui-même est acquis. Si vous ne décrivez pas cela, la recherche correspondante qui est appelée pour Post ne sera pas trouvée et une erreur se produira. __

_ * Actuellement, le problème de non affichage des publications avec 0 likes n'est pas pris en charge. Je suis désolé…. Je l'ajouterai dès qu'il sera résolu. _

5. Afficher la vue des résultats de la recherche

Résultats de la recherche h1   = form_with url: search_path, method: :get, local: true do |form| = form.select :keyword, [ ['Les messages sont les plus récents', 'new'], ['Messages les plus anciens', 'old'], ['Par ordre décroissant de likes', 'likes'], ['Dans l'ordre croissant des likes', 'dislikes'], ] = form.submit


 >> __ ・ Créez un fichier setatch.html.slim dans le répertoire app / views / posts et décrivez-le comme ci-dessus. __
 
 >> __ ・ Le contenu décrit ici est exactement le même que le contenu décrit dans posts / index.html.slim, il sera donc partial. __

### 6. Vue partielle

 > #### __6-1. Partialisation du formulaire de recherche __

>```ruby:app/views/posts/_select_form.html.slim
= form_with model: @post, url: search_path, method: :get, local: true do |form|
  = form.select :keyword, [ ['Les messages sont les plus récents', 'new'],
                            ['Messages les plus anciens', 'old'],
                            ['Par ordre décroissant de likes', 'likes'],
                            ['Dans l'ordre croissant des likes', 'dislikes'],
                          ]
  = form.submit

__ · Créez un fichier _select_form.html.slim dans le répertoire app / views / posts et portez l'intégralité du code du menu déroulant. __

__6-2. Partialisation de la liste des articles et de la liste des résultats de la recherche __


 >> __ ・ Créez un fichier `_result.html.slim` dans le répertoire app / views / posts et portez l'intégralité du code pour afficher la liste des publications. __

 > #### __6-3. Rendu à chaque vue __

>```ruby:app/views/posts/index.html.slim
Liste des messages h1
 
= render 'select_form'
 
= render 'result'

Résultats de la recherche h1   = render 'select_form'   = render 'result'


#### c'est tout.


## finalement
 Ceci termine l'implémentation de la fonction de tri!
 Pour être honnête, je ne suis pas confiant dans de nombreux domaines, alors je serais très heureux si vous pouviez me dire quelque chose de mal!

## Article très utile
 [Comment implémenter la fonction de recherche sans gemme? Prend en charge plusieurs tables! ](Https://prokyou.com/rails/nogemsearch/)
 [[Rails] Comment utiliser select pour créer une boîte de sélection avec un formulaire de compréhension complet](https://310nae.com/rails-selectbox/)
[select (ActionView::Helpers::FormOptionsHelper) - APIdock](https://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/select)


Recommended Posts

[Rails] Utilisez la zone déroulante pour trier la liste des articles par date ou par nombre de likes.
[Enum] Utilisez des rails enum pour améliorer la lisibilité des données
[Rails] Enregistrez-vous par attribut du même modèle en utilisant Devise
Lorsque vous utilisez le constructeur de la classe Date de Java, la date avance de 1900.
[Rails] Comment afficher une liste de messages par catégorie
Trier par nombre de likes et par nation de page
Comment trier une liste de SelectItems
[Rails] Mise en œuvre du classement des nombres PV à l'aide de l'impressionniste
Une revue du code utilisé par les rails débutants
[Java] Trier la liste à l'aide de flux et d'expressions lambda
Trouvez le reste divisé par 3 sans utiliser de nombre
Rails6: saisissez les données initiales d'ActionText à l'aide de seed
Sortie du jour en utilisant la classe Ruby's Date
Limiter le nombre de threads à l'aide du service d'exécution de Java
Essayez d'utiliser l'attribut de requête Ruby on Rails