Veraltete Warnung für Rails 4 has_many mit Bestellung


105
class RelatedList < ActiveRecord::Base
  extend Enumerize

  enumerize :list_type, in: %w(groups projects)

  belongs_to :content
  has_many :contents, :order => :position

end

Ich habe dieses Modell in meiner Rails-App, die eine Warnung auslöst, wenn ich versuche, Datensätze in der Konsole zu erstellen.

DEPRECATION WARNING: Die folgenden Optionen in Ihrer RelatedList.has_many: Inhaltsdeklaration sind veraltet :: order. Bitte verwenden Sie stattdessen einen Bereichsblock. Beispiel: has_many: spam_comments, Bedingungen: {spam: true}, Klassenname: 'Kommentar' sollte wie folgt umgeschrieben werden: has_many: spam_comments, -> {wobei Spam: wahr}, Klassenname: 'Kommentar'. (aufgerufen von /Users/shivam/Code/auroville/avorg/app/models/related_list.rb:7)

Es scheint, als ob Rails 4 eine neue Syntax für die Verwendung in Modellen hat, aber ich kann die Dokumentation in Rails Guides nicht finden.

Antworten:


250

In Rails 4 :orderist es veraltet und muss durch einen Lambda-Scope-Block ersetzt werden, wie in der Warnung gezeigt, die Sie in der Frage gepostet haben. Ein weiterer zu beachtender Punkt ist, dass dieser Bereichsblock vor allen anderen Zuordnungsoptionen wie dependent: :destroy usw. übergeben werden muss.

Probieren Sie es aus:

has_many :contents, -> { order(:position) }

Verwenden Sie zum Festlegen der Bestellrichtung , dh entweder ascoder descwie von @ joshua-coady und @wsprujit vorgeschlagen, Folgendes:

has_many :contents, -> { order 'position desc' }

oder mit dem Hash-Stil:

has_many :contents, -> { order(position: :desc) }

Weitere Referenz zu Active Record Scopes fürhas_many .


3
funktioniert hervorragend! Wo finde ich solche Informationen in den Handbüchern oder Dokumenten? Ich kann keinen finden. Vielen Dank.
Shankardevy


4
Was ist, wenn Sie mehr als eine veraltete Option haben, sagen wir oderund include? Dies: { order(:position), include(:track) }Wirft einen Fehler auf das Komma.
Kakubei

2
Verwenden Sie für die Bestellung von Asc / Desc-> { order(name: :asc) }
wspruijt

1
Wenn Sie aus irgendeinem Grund nur möchten, dass die Sammlung einige Male bestellt wird, können Sie dies auch tun, list.contents.order('position desc')was insgesamt effizienter und nicht als aufdringliches Modell sein kann (in der abgestimmten Antwort kennt die Liste ein Inhaltsfeld, hier weiß es der Controller )
Dirty Henry

35

Es hat eine Weile gedauert, bis ich herausgefunden hatte, wie man bestellt und einschließt. Schließlich stellte ich fest, dass Sie die Scope- Anweisungen verketten.

has_many :things, -> { includes(:stuff).order("somedate desc") }, class_name: "SomeThing"

2
Das war genau mein Problem. Der Versuch, herauszufinden, wie eine has_many-Beziehung nach einem übergeordneten Attribut geordnet wird. Wusste nicht, dass Sie solche Includes machen und dann bestellen können. Vielen Dank!
Timothyashaw

26

Ich dachte nur, ich würde hinzufügen, dass, wenn Sie Options-Hash-Argumente haben, diese dem Lambda folgen müssen, wie folgt:

has_many :things, -> { order :stuff }, dependent: :destroy

Ich habe eine Minute gebraucht, um das selbst herauszufinden - hoffentlich hilft es allen anderen, die zu dieser Frage kommen und das gleiche Problem haben.


3
Dies gilt auch für "durch" Assoziationen, die auf dem Objekt existieren könnten -has_many :items, -> { order 'name' }, through: :suppliers
Major Major

0

Dies funktioniert bei mir mit Rails 4 & MongoDB

has_many :discounts, order: :min_amount.asc

-4

Alternativ können Sie die orderKlausel in das Modell einfügen, zum Beispiel:

has_many :options, order: 'name' # In class Answer

Wird

has_many :options # In class Answer

default_scope { order 'name' } # In class Option

PS: Ich habe ArgumentError: wrong number of arguments (1 for 0)dabei has_many :things, -> {}.


4
Verwenden Sie nicht den Standardbereich. Wenn Sie es gewohnt sind, können Sie in dieser magischen Methode mehr Logik hinzufügen. Es ist schwer, es in Zukunft zu überschreiben.
Grzegorz Łuszczek
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.