96 votes

Comment trier automatiquement une relation has_many dans Rails?

Cela semble être une question très simple mais je ne l’ai pas vue répondre nulle part.

En rails si vous avez:

 class Article < ActiveRecord::Base 
  has_many :comments 
end 
class Comments < ActiveRecord::Base 
  belongs_to :article 
end
 

Pourquoi ne pouvez-vous pas commander les commentaires avec quelque chose comme ceci:

 @article.comments(:order=>"created_at DESC")
 

La portée nommée fonctionne si vous devez y faire beaucoup référence et que même les gens font des choses comme celle-ci:

 @article.comments.sort { |x,y| x.created_at <=> y.created_at }
 

Mais quelque chose me dit que cela devrait être plus simple. Qu'est-ce que je rate?

148voto

Jim Puls Points 29289

Vous pouvez spécifier l'ordre de tri pour le nu de la collection, avec une option sur has_many lui-même:

class Article < ActiveRecord::Base 
  has_many :comments, :order => 'created_at DESC'
end 
class Comment < ActiveRecord::Base 
  belongs_to :article 
end

Ou, si vous voulez un moyen simple, non-base de données méthode de tri, utilisation sort_by:

article.comments.sort_by &:created_at

La collecte de ce avec la ActiveRecord-ajout des méthodes de commande:

article.comments.find(:all, :order => 'created_at DESC')
article.comments.all(:order => 'created_at DESC')

Votre kilométrage peut varier: les caractéristiques de performance des solutions ci-dessus va changer sauvagement en fonction de la façon dont vous êtes, extraction de données, en premier lieu, et qui Ruby vous utilisez pour exécuter votre application.

7voto

nitecoder Points 4561

Si vous utilisez Rails 2.3 et souhaitez utiliser le même ordre par défaut pour toutes les collections de cet objet, vous pouvez utiliser default_scope pour commander votre collection.

 class Student < ActiveRecord::Base
  belongs_to :class

  default_scope :order => 'name'

end
 

Alors si vous appelez

 @students = @class.students
 

Ils seront commandés selon votre default_scope. TBH, dans un sens très général, est la seule utilisation vraiment efficace des portées par défaut.

6voto

vrish88 Points 3918

Vous pouvez utiliser la méthode de recherche d'ActiveRecord pour obtenir vos objets et les trier aussi.

   @article.comments.find(:all, :order => "created_at DESC")
 

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X