39 votes

Rails order by dans le modèle associé

J'ai deux modèles dans une relation has_many telle que Log has_many Items. Rails met alors en place des éléments tels que : some_log.items qui renvoie tous les éléments associés à some_log. Si je voulais ordonner ces éléments sur la base d'un champ différent dans le modèle Items, y a-t-il un moyen de le faire par une construction similaire, ou doit-on se décomposer en quelque chose comme :

Item.find_by_log_id(:all,some_log.id => "some_col DESC")

0voto

Matthew Points 15

Pour tous ceux qui rencontrent cette question en utilisant des versions plus récentes de Rails, le deuxième argument de l'option has_many est une portée facultative depuis Rails 4.0.2. Exemples de les docs (voir les exemples de champs d'application et d'options) incluent :

has_many :comments, -> { where(author_id: 1) }
has_many :employees, -> { joins(:address) }
has_many :posts, ->(blog) { where("max_post_length > ?", blog.max_post_length) }
has_many :comments, -> { order("posted_on") }
has_many :comments, -> { includes(:author) }
has_many :people, -> { where(deleted: false).order("name") }, class_name: "Person"
has_many :tracks, -> { order("position") }, dependent: :destroy

Comme répondu précédemment, vous pouvez également passer un bloc à has_many . "Ceci est utile pour ajouter de nouveaux trouveurs, créateurs et autres méthodes de type usine à utiliser dans le cadre de l'association." ( même référence - voir Extensions).

L'exemple qui y est donné est le suivant :

has_many :employees do
  def find_or_create_by_name(name)
    first_name, last_name = name.split(" ", 2)
    find_or_create_by(first_name: first_name, last_name: last_name)
  end
end

Dans les versions plus modernes de Rails, l'exemple de l'OP pourrait être écrit :

class Log < ApplicationRecord
  has_many :items, -> { order(some_col: :desc) }
end

Gardez à l'esprit que cette méthode présente tous les inconvénients des paramètres par défaut. Vous préférerez peut-être l'ajouter en tant que méthode distincte :

class Log < ApplicationRecord
  has_many :items

  def reverse_chronological_items
    self.items.order(date: :desc)
  end
end

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