Apa itu scope / Named_scope di rel?

105

Saya baru saja mulai magang. Majikan saya menggunakan ruby ​​on rails, dan saya sering menemukan sintaks baru yang perlu saya cari untuk dipahami. Saya telah mencari-cari penjelasan yang baik tentang names_scope di Google, tetapi yang saya temukan sejauh ini kebanyakan posting blog yang memberikan pujian tinggi untuk itu, bukan definisi atau pengantar langsung.

Apa sebenarnya yang dimaksud dengan names_scope (sekarang disebut scope) di ruby ​​on rails?

Ziggy
sumber
kemungkinan duplikat dari Apa pentingnya lingkup bernama di Rails?
jdl
2
Entri blog ini sangat berharga bagi saya saat mempelajari cakupan bernama: ryandaigle.com/articles/2008/8/20/…
Peter Brown
@notapatch linknya sudah mati apakah anda punya yang lain?
mbigras
Ryan Daigle: Lingkup Bernama: Ini Bukan Hanya untuk Kondisi, Ya Tahu ?: web.archive.org/web/20160306110506/http://…
notapatch

Jawaban:

212

Cakupan adalah bagian dari koleksi. Kedengarannya rumit? Tidak. Bayangkan ini:

Anda memiliki Pengguna. Sekarang, beberapa dari Pengguna tersebut berlangganan buletin Anda. Anda menandai mereka yang menerima buletin dengan menambahkan bidang ke Database Pengguna (user.subscribed_to_newsletter = true). Biasanya, terkadang Anda ingin mendapatkan Pengguna yang berlangganan buletin Anda.

Anda dapat, tentu saja, selalu melakukan ini:

User.where(subscribed_to_newsletter: true).each do #something

Alih-alih selalu menulis ini, Anda dapat melakukan sesuatu seperti ini.

#File: users.rb
class User < ActiveRecord::Base
  scope :newsletter, where(subscribed_to_newsletter: true)
  #yada yada
end

Jika Anda menggunakan Rails 4 atau yang lebih baru , lakukan ini sebagai gantinya:

#File: users.rb
class User < ActiveRecord::Base
  scope :newsletter, -> { where(subscribed_to_newsletter: true) }
  #yada yada
end

Ini memungkinkan Anda untuk mengakses pelanggan Anda hanya dengan melakukan ini:

User.newsletter.each do #something

Ini adalah contoh yang sangat sederhana tetapi secara umum cakupan dapat menjadi alat yang sangat berguna untuk memudahkan pekerjaan Anda.

Lihat tautan ini: Deskripsi API

Michael Schäfermeyer
sumber
7
Dapatkah saya bertanya apa keuntungan dari ini daripada mengatakan mendefinisikan metode di Kelas Pengguna yang disebut 'subscedUsers'? mis. 'def self.subscribedUsers self.where (: subsced_to_newsletter => true) end
redroot
3
@redroot keuntungannya adalah scopesintaksnya jauh lebih bersih, Anda mendapatkan hasil yang sama tetapi hanya dengan satu baris
Aldo 'xoen' Giambelluca
9
@redroot Dulu ada keuntungan efisiensi yang besar, karena cakupan akan meminta database dengan malas sementara metode akan melakukannya dengan bersemangat. Di Rails 3, metode menjadi malas juga, jadi sekarang perbedaannya lebih sintaksis. Sumber
evanrmurphy
Tautan dokumen API rusak, harap perbarui api.rubyonrails.org/classes/ActiveRecord/Scoping/Named/…
Lohith MV
Juga memungkinkan menggunakan tautan
terbatas
34

ruang lingkup dalam catatan aktif seperti metode kelas tetapi mereka mengembalikan objek Relasi yang berarti Anda dapat memanggil ruang lingkup atau metode kueri rekaman aktif di atasnya.

Misalnya, jika Anda memiliki model Zombie (tabel zombie) dengan metode lingkup yang disebutkan di bawah ini,

class Zombie
  scope :rotting, -> { where(rotting: true) }
  scope :fresh, -> { where('age < ?', 25) }
  scope :recent, -> { order(created_at: :desc) }
end

Dan Anda menelepon

Zombie.rotting.fresh.recent.limit(3)

Ini diterjemahkan ke bawah dalam SQL,

select "zombies.*" from "zombies" where "zombies"."rotting" = 't' and (age<20) order by create_at desc limit 3

Contoh di atas didasarkan pada sintaks rails 4

Akshatha
sumber
Saya tidak dapat menemukan contoh order (: create_at,: desc) di dokumentasi manapun. Mungkinkah yang Anda maksud scope :recent, -> { order(created_at: :desc) }? apidock.com/rails/v4.2.9/ActiveRecord/QueryMethods/order
notapatch
7

Cara terbaik untuk memahami detailnya adalah dengan membuka Dokumentasi API.

Anda akan mendapatkan detail lengkap dan cara kami menggunakan Cakupan.

Dokumentasi Ruang Lingkup API

123
sumber
7

Cakupan tidak lain adalah metode kelas.

Mengapa menggunakannya?

Scoping memungkinkan Anda untuk menentukan kueri yang umum digunakan (dapat dianggap sebagai pintasan untuk kueri yang panjang atau paling sering digunakan) yang dapat dirujuk sebagai panggilan metode pada objek atau model asosiasi. Dengan cakupan ini, Anda dapat menggunakan setiap metode yang telah dibahas sebelumnya seperti di mana, bergabung, dan disertakan. Semua metode lingkup akan mengembalikan objek ActiveRecord :: Relation yang memungkinkan metode lebih lanjut (seperti cakupan lain) untuk dipanggil.

Untuk mendefinisikan ruang lingkup sederhana, kami menggunakan metode lingkup di dalam kelas, meneruskan kueri yang ingin kami jalankan ketika lingkup ini dipanggil:

class Article < ActiveRecord::Base
  scope :published, -> { where(published: true) }
end

Ini persis sama dengan mendefinisikan metode kelas, dan yang Anda gunakan adalah masalah preferensi pribadi:

class Article < ActiveRecord::Base
  def self.published
    where(published: true)
  end
end

Silakan ikuti tautan berikut untuk deskripsi lengkap dengan contoh. Saya harap ini akan membantu Anda.

http://guides.rubyonrails.org/active_record_querying.html

Imran Ahmad
sumber
3
Ini tidak persis sama dengan mendefinisikan metode kelas . Metode kelas kembali nildalam beberapa kasus, dan karenanya tidak dapat dirantai untuk kondisi tertentu.
Arslan Ali
1
  • Bayangkan Anda memiliki model: Orang .

Sekarang bayangkan Anda:

  • ingin semua orang di dunia yang berambut merah.
  • ingin semua orang di dunia yang bermain kriket

Anda bisa mendapatkan kelas orang-orang tertentu itu dengan menggunakan sebuah scope!

Person.red_hair.cricket ## finds all people with red hair who play cricket
Person.red_hair ## finds all people with red hair
Person.cricket ## finds all people who play cricket.

Sekarang tidak terlalu sulit, bukan?

BKSpurgeon
sumber