3
votes

Scope Order by Count with Conditions Rails

J'ai un modèle Category qui a_many Pendencies . Je voudrais créer une portée qui ordonne les catégories en fonction du nombre de Pendencies qui a active = true sans exclure active = false .

Ce que j'ai jusqu'à présent, c'est :

scope :order_by_pendencies, -> { left_joins(:pendencies).group(:id).where('pendencies.active = ?', true).order('COUNT(pendencies.id) DESC')}

Cela le classera par nombre de pendentifs, mais je veux classer par pendentifs qui a active = true .

Un autre essai a été:

scope :order_by_pendencies, -> { left_joins(:pendencies).group(:id).order('COUNT(pendencies.id) DESC')}

Cela classera par nombre de pendances qui ont pendencies.active = true , mais exclura le pendencies.active = false .

Merci pour votre aide.


4 commentaires

Hé mec. La balise de commande indique ne pas utiliser. Je ne comprends pas très bien votre question mais la balise doit disparaître.


Bonjour Joshua. Merci pour la réponse. Je n'ai pas vraiment compris ce que vous entendez par étiquette de commande. Ma question est la suivante: imaginez que j'ai ce qui suit: catégorie 1 avec 10 pendances (2 actifs = vrai et 8 actifs = faux); catégorie 2 avec 8 pendances (6 actives = vraies et 2 actives = fausses); catégorie 3 avec 15 pendances (15 actives = faux) Je veux que l'ordre soit: Catégorie 2, Catégorie 1, Catégorie 3


Je pourrais résoudre ce problème en C #. Désolé, je ne connais pas Ruby.


Merci d'avoir essayé, Jushua. Pourriez-vous s'il vous plaît poster votre réponse en C #? Peut-être que je peux avoir un aperçu si je le vois


3 Réponses :


1
votes

Réponse C # comme demandé:

SELECT category.id, ..., ActivePendnecies
  FROM (SELECT category.id, ..., count(pendency) ActivePendnecies
          FROM category
          LEFT JOIN pendency ON category.id = pendency.id AND pendnecy.Active = 1
          GROUP BY category.id, ...) P
 ORDER BY ActivePendnecies;

Ou en SQL simple:

method() {
    ....OrderBy((category) => category.Count(pendencies.Where((pendency) => pendency.Active))
}

Nous devons afficher ActivePendnecies code > en SQL même si le code le rejettera car sinon, l'optimiseur est en droit de rejeter le ORDER BY .


0 commentaires

0
votes

Pour l'instant, j'ai développé ce qui suit (ça marche, mais je pense que ce n'est pas la meilleure façon):

  scope :order_by_pendencies, -> { scoped = Category.left_joins(:pendencies)
                                            .group(:id)
                                            .order('COUNT(pendencies.id) DESC')
                                            .where('pendencies.active = ?', true)
                                   all = Category.all
                                   (scoped + all).uniq}


0 commentaires

1
votes

Je suppose que vous voulez trier par le nombre de suspensions actives sans ignorer les catégories qui n'ont pas de suspensions actives.

Ce serait quelque chose comme:

SELECT *, ac.count 
FROM categories
LEFT JOIN (
    SELECT category_id, COUNT(*) AS count
    FROM pendencies
    GROUP BY category_id
    WHERE active = true
  ) AS ac ON ac.category_id = id
ORDER BY ac.count DESC

L'équivalent Requête SQL:

scope :order_by_pendencies, -> { 
  active_count_q = Pendency.
    group(:category_id).
    where(active: true).
    select(:category_id, "COUNT(*) AS count")

  joins("LEFT JOIN (#{active_count_q.to_sql}) AS ac ON ac.category_id = id").
    order("ac.count DESC")
}

Notez que s'il n'y a pas de suspensions actives pour une catégorie, le décompte sera nul et sera ajouté à la fin de la liste. Une sous-requête similaire pourrait être ajoutée pour trier en plus par le nombre total de suspensions ...


0 commentaires