Peringatan yang tidak berlaku lagi untuk Rails 4 memiliki_many dengan pesanan

105
class RelatedList < ActiveRecord::Base
  extend Enumerize

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

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

end

Saya memiliki model ini di aplikasi rel saya yang memberi peringatan ketika saya mencoba membuat catatan di konsol.

PERINGATAN PERHATIAN: Opsi berikut di RelatedList.has_many Anda: deklarasi konten tidak berlaku lagi:: order. Silakan gunakan blok lingkup sebagai gantinya. Misalnya, berikut ini: has_many: spam_comments, condition: {spam: true}, class_name: 'Comment' harus ditulis ulang sebagai berikut: has_many: spam_comments, -> {where spam: true}, class_name: 'Comment'. (dipanggil dari di /Users/shivam/Code/auroville/avorg/app/models/related_list.rb:7)

Sepertinya Rails 4 memiliki sintaks baru: urutan untuk digunakan dalam model tetapi saya tidak dapat menemukan dokumentasinya di Rails Guides.

shankardevy
sumber

Jawaban:

250

Di Rails 4, :ordersudah tidak digunakan lagi dan perlu diganti dengan blok lingkup lambda seperti yang ditunjukkan dalam peringatan yang Anda posting dalam pertanyaan. Hal lain yang perlu diperhatikan adalah bahwa blok cakupan ini perlu diteruskan sebelum opsi asosiasi lain seperti dependent: :destroy dll.

Cobalah ini:

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

Untuk menentukan arah pesanan, yaitu, ascatau descseperti yang disarankan @ joshua-coady dan @wsprujit, gunakan:

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

atau, menggunakan gaya hash:

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

Referensi lebih lanjut tentang Lingkup Rekaman Aktif untukhas_many .

vee
sumber
3
bekerja luar biasa! di mana saya dapat menemukan informasi seperti itu di panduan atau dokumen? Saya tidak dapat menemukannya. Terima kasih.
shankardevy
4
Bagaimana jika Anda memiliki lebih dari satu opsi yang tidak berlaku lagi, katakan oderdan include? Ini: { order(:position), include(:track) }melempar kesalahan pada koma.
kakubei
2
Untuk memesan asc / desc, gunakan-> { order(name: :asc) }
wspruijt
1
Jika karena alasan tertentu, Anda hanya ingin koleksi diurutkan beberapa kali, Anda juga dapat melakukan list.contents.order('position desc')yang bisa lebih efisien secara keseluruhan, dan bukan sebagai model yang mengganggu (dalam jawaban yang dipilih, daftar mengetahui bidang konten, di sini pengontrol mengetahuinya )
Dirty Henry
35

Butuh beberapa saat bagi saya untuk memikirkan cara melakukan pemesanan dan memasukkan, saya akhirnya menemukan bahwa Anda merangkai pernyataan cakupan ,

has_many :things, -> { includes(:stuff).order("somedate desc") }, class_name: "SomeThing"
sfoop
sumber
2
Ini persis masalah saya. Mencoba mencari cara untuk memesan hubungan has_many dengan atribut induk. Tidak sadar Anda bisa melakukan termasuk seperti ini dan kemudian memesan. Terima kasih!
timothyashaw
27

Hanya berpikir saya akan menambahkan bahwa jika Anda memiliki argumen hash opsi, mereka harus mengejar lambda, seperti ini:

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

Butuh waktu satu menit untuk mencari tahu sendiri - mudah-mudahan ini membantu orang lain yang datang ke pertanyaan ini yang memiliki masalah yang sama.

Wylliam Judd
sumber
3
Ini juga berlaku untuk asosiasi "melalui" yang mungkin ada pada objek -has_many :items, -> { order 'name' }, through: :suppliers
Mayor Mayor
0

Ini berfungsi untuk saya dengan Rails 4 & MongoDB

has_many :discounts, order: :min_amount.asc
Dave
sumber
-4

Sebagai alternatif, Anda dapat meletakkan orderklausa pada model, misalnya:

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

Menjadi

has_many :options # In class Answer

default_scope { order 'name' } # In class Option

PS: Saya dapat ArgumentError: wrong number of arguments (1 for 0)saat melakukan has_many :things, -> {}.

Dorian
sumber
4
Jangan gunakan cakupan default. Jika Anda terbiasa melakukannya, Anda dapat menambahkan lebih banyak logika ke metode ajaib itu. Sulit untuk menggantinya di masa depan.
Grzegorz Łuszczek