ฉันต้องการระบุลำดับการจัดเรียงเริ่มต้นในโมเดลของฉัน
ดังนั้นเมื่อฉันทำ.where()
โดยไม่ระบุ.order()
มันใช้การเรียงลำดับเริ่มต้น แต่ถ้าฉันระบุ.order()
มันมันจะแทนที่ค่าเริ่มต้น
ฉันต้องการระบุลำดับการจัดเรียงเริ่มต้นในโมเดลของฉัน
ดังนั้นเมื่อฉันทำ.where()
โดยไม่ระบุ.order()
มันใช้การเรียงลำดับเริ่มต้น แต่ถ้าฉันระบุ.order()
มันมันจะแทนที่ค่าเริ่มต้น
คำตอบ:
default_scope
ใช้งานได้กับ Rails 4+:
class Book < ActiveRecord::Base
default_scope { order(created_at: :desc) }
end
สำหรับ Rails 2.3, 3 คุณต้องการสิ่งนี้แทน:
default_scope order('created_at DESC')
สำหรับ Rails 2.x:
default_scope :order => 'created_at DESC'
ไหนcreated_at
เป็นเขตที่คุณต้องการเริ่มต้นการเรียงลำดับที่จะต้องทำใน
หมายเหตุ: ASCเป็นรหัสที่จะใช้สำหรับ Ascending แยกและDESCสำหรับลงมา ( desc
, ไม่ได้ dsc
!)
scope
เมื่อคุณคุ้นเคยกับสิ่งนั้นแล้วคุณยังสามารถใช้scope
:
class Book < ActiveRecord::Base
scope :confirmed, :conditions => { :confirmed => true }
scope :published, :conditions => { :published => true }
end
สำหรับทางรถไฟ 2 named_scope
ที่คุณต้องการ
:published
ขอบเขตช่วยให้คุณแทน Book.published
Book.find(:published => true)
ตั้งแต่ Rails 3 คุณสามารถ 'เชื่อมโยง' วิธีการเหล่านั้นเข้าด้วยกันด้วยการเชื่อมต่อมันเข้ากับช่วงเวลาระหว่างพวกเขาดังนั้นด้วยขอบเขตด้านบนคุณสามารถใช้งานBook.published.confirmed
ได้แล้ว
ด้วยวิธีนี้แบบสอบถามจะไม่ถูกดำเนินการจริง ๆ จนกว่าจะต้องการผลลัพธ์ที่แท้จริง (การประเมินแบบสันหลังยาว) ดังนั้นขอบเขต 7 รายการจึงสามารถถูกโยงเข้าด้วยกัน แต่ส่งผลให้เกิด 1 แบบสอบถามฐานข้อมูลจริงเท่านั้นเพื่อหลีกเลี่ยงปัญหาประสิทธิภาพการทำงาน
คุณสามารถใช้พารามิเตอร์ส่งผ่านเช่นวันที่หรือ user_id (สิ่งที่จะเปลี่ยนแปลงในเวลาทำงานและจะต้องมี 'การประเมินผลที่ขี้เกียจ' กับแลมบ์ดาเช่นนี้:
scope :recent_books, lambda
{ |since_when| where("created_at >= ?", since_when) }
# Note the `where` is making use of AREL syntax added in Rails 3.
ในที่สุดคุณสามารถปิดใช้งานขอบเขตเริ่มต้นด้วย:
Book.with_exclusive_scope { find(:all) }
หรือดีกว่า:
Book.unscoped.all
ซึ่งจะปิดการใช้งานตัวกรอง (เงื่อนไข) หรือเรียงลำดับ (เรียงตาม)
โปรดทราบว่ารุ่นแรกทำงานใน Rails2 + ในขณะที่รุ่นที่สอง (ไม่ระบุขนาด) ใช้สำหรับ Rails3 + เท่านั้น
ดังนั้น
... ถ้าคุณกำลังคิดอืมดังนั้นนี่ก็เป็นวิธีการเหมือนกัน ... , ใช่นั่นคือสิ่งที่ขอบเขตเหล่านี้!
พวกเขาเป็นเหมือนมีdef self.method_name ...code... end
แต่กับทับทิมเสมอพวกเขามีทางลัด syntax (หรือ 'น้ำตาล') เพื่อให้ทุกอย่างง่ายขึ้นสำหรับคุณ!
ในความเป็นจริงพวกเขาเป็นวิธีการเรียนระดับที่พวกเขาทำงานใน 1 ชุดของระเบียน 'ทั้งหมด'
รูปแบบของพวกเขากำลังเปลี่ยนแปลงอย่างไรก็ตามด้วย Rails 4 จะมีคำเตือนการคัดค้านเมื่อใช้ #scope โดยไม่ผ่านวัตถุที่เรียกได้ ยกตัวอย่างเช่นขอบเขต: สีแดง, ที่ (สี: 'red') scope :red, -> { where(color: 'red') }
ควรจะเปลี่ยนไป
ในฐานะที่เป็นบันทึกด้านข้างเมื่อใช้อย่างไม่ถูกต้อง_scope ที่เป็นค่าเริ่มต้นอาจถูกนำไปใช้ในทางที่ผิด / ถูกใช้ในทางที่ผิด
นี่เป็นเรื่องเกี่ยวกับเวลาที่มันถูกใช้สำหรับการกระทำเช่นwhere
การ จำกัด (การกรอง) การเลือกเริ่มต้น ( ความคิดที่ไม่ดีสำหรับการเริ่มต้น) แทนที่จะใช้เพื่อการสั่งซื้อผลลัพธ์เท่านั้น
สำหรับการwhere
เลือกเพียงใช้ขอบเขตปกติที่มีชื่อ และเพิ่มขอบเขตนั้นในแบบสอบถามเช่นBook.all.published
ที่ไหนpublished
เป็นขอบเขตที่มีชื่อ
สรุปแล้วขอบเขตนั้นยอดเยี่ยมมากและช่วยให้คุณผลักดันสิ่งต่างๆเข้าสู่โมเดลสำหรับแนวทาง DRYer 'fat model thin'
default_scope { order("#{table_name}.created_at DESC") }
ไหมถ้าจะทำ?
default_scope { order(created_at: :desc) }
4.2.6
ดูเหมือนว่าจะเรียงลำดับตามไม่ได้updated_at
created_at
updated_at
ตามค่าเริ่มต้น? : - |
การอัปเดตอย่างรวดเร็วสำหรับคำตอบที่ยอดเยี่ยมของ Michael ด้านบน
สำหรับ Rails 4.0+ คุณจะต้องเรียงลำดับของคุณในบล็อกดังนี้:
class Book < ActiveRecord::Base
default_scope { order('created_at DESC') }
end
ขอให้สังเกตว่าคำสั่งคำสั่งจะถูกวางไว้ในบล็อกที่แสดงโดยวงเล็บปีกกา
พวกเขาเปลี่ยนมันเพราะมันง่ายเกินกว่าที่จะผ่านไปในสิ่งที่มีพลัง (เช่นเวลาปัจจุบัน) สิ่งนี้จะลบปัญหาเนื่องจากบล็อกถูกประเมินที่รันไทม์ หากคุณไม่ใช้บล็อกคุณจะได้รับข้อผิดพลาดนี้:
การสนับสนุนสำหรับการโทร #default_scope ที่ไม่มีบล็อกถูกลบออก ตัวอย่างเช่นแทนที่จะกรุณาใช้
default_scope where(color: 'red')
default_scope { where(color: 'red') }
(อีกทางหนึ่งคุณสามารถกำหนด self.default_scope ใหม่ได้)
ตามที่@Danกล่าวถึงในความคิดเห็นของเขาด้านล่างคุณสามารถทำไวยากรณ์ rubyish เพิ่มเติมเช่นนี้:
class Book < ActiveRecord::Base
default_scope { order(created_at: :desc) }
end
หรือมีหลายคอลัมน์:
class Book < ActiveRecord::Base
default_scope { order({begin_date: :desc}, :name) }
end
ขอบคุณ@ แดน !
default_scope { order(created_at: :desc) }
ได้เหมือนเช่นฉันคุณพยายามลดไวยากรณ์ของ sql ในรางให้น้อย <br/> หากคุณมีหลายคอลัมน์ที่จะเรียงตามและคุณต้องการใช้ไวยากรณ์ใหม่ คอลัมน์ในหนวดแบบนี้default_scope { order({begin_date: :desc}, :name) }
คุณสามารถใช้ default_scope เพื่อใช้การเรียงลำดับเริ่มต้นได้ที่ http://api.rubyonrails.org/classes/ActiveRecord/Scoping/Default/ClassMethods.html
default_scope
ในหน้านั้นเพราะได้รับการ refactored จากActiveRecord::Base
เข้าActiveRecord::Scoping::Default::ClassMethods
( api.rubyonrails.org/classes/ActiveRecord/Scoping/Default/... )