ขอบเขตกับแลมบ์ดาและการโต้แย้งในสไตล์ Rails 4 หรือไม่


144

ฉันสงสัยว่าจะทำสิ่งต่อไปนี้อย่างไรใน Rails 4 หรือถ้าฉันใช้ Rails 3 ในการใช้แลมบ์ดาที่สามารถทะเลาะกันด้วยวิธีเดียวกับ 4 เช่นเดียวกับ 3

ฉันค่อนข้างใหม่กับ Rails 3 และพยายามทำงานกับตัวอย่างบางส่วนที่ใช้งาน Rails 4

นี่คือรหัส Rails 3 ของฉัน:

class Person < ActiveRecord::Base
  scope :find_lazy, lambda {|id| where(:id => id)}
end

# In console I can call
Person.find_lazy(1)

ดังนั้นถ้านี่คือ Rails 4 ทางคือใช้ -> {} นั่นคือแลมบ์ดาใช่ไหม? scope :all_lazy, -> { select("*") }ถ้าฉันต้องการการโต้แย้ง ฉันลองแนวคิดที่แตกต่างกันสองสามข้อและรับข้อผิดพลาดการโต้แย้งในคอนโซลเมื่อใช้ -> {}

คำตอบ:


305

ฉันคิดว่ามันควรจะเป็น:

scope :find_lazy, -> (id) { where(id: id) }

2
เอกสารประกอบการสนับสนุนส่วนที่ 14.1 โดยเฉพาะ
เดนนิส

3
Yay ช่วยฉันเขียนscope :in_daterange, ->(start_date, end_date) { where(created_at: start_date.to_date.beginning_of_day..end_date.to_date.end_of_day) }
Epigene

4
โปรดทราบว่าหากคุณใช้ Ruby 1.9 ไวยากรณ์แลมบ์ดาสั้นจะไม่อนุญาตให้มีช่องว่างระหว่างลูกศรและพารามิเตอร์ ( scope :find_lazy, ->(param)) ใน Ruby 2+ อนุญาตให้ใช้พื้นที่ว่างได้ ข้อมูลเพิ่มเติมที่นี่ ...
furman87

"Modern" syntex ใน Rubyscope :find_lazy, -> id { where id: id }
swordray

11

Ruby ไม่ได้คัดค้านแลมบ์ดาแบบเก่าดังนั้นหากคุณรู้สึกว่าการใช้แลมบ์ดานั้นสะดวกกว่า

ฉันไม่ชอบรูปแบบไวยากรณ์ของแลมบ์ดาโดยส่วนตัว แต่ในที่สุดพวกเขาอาจกลายเป็นบรรทัดฐานดังนั้นจึงไม่เจ็บที่จะคุ้นเคยกับพวกเขา


6
ฉันชอบไวยากรณ์ แต่รู้สึกผิดปกติที่จะวางข้อโต้แย้งระหว่างลูกศรและตัวฟังก์ชันในขณะที่มันควรจะเป็น "(id) -> {ที่ไหน ... }" ซึ่งน่าสนใจมากกว่านี้ (และจะไม่ ทำลายด้วยความรู้คณิตศาสตร์ของฉันหรือไวยากรณ์ coffeescript) ในที่สุด "->" พูดว่าคล้ายกับการจับคู่ค่ากับผลลัพธ์
hurikhan77

ฉันวิ่งเข้าไปในสถานการณ์ที่ใช้รูปแบบเก่าใน Rails 4.2 กำลังคืนค่าบูลีนที่ไม่ถูกต้องจากฐานข้อมูล อาจไม่ได้เลิกใช้อย่างเป็นทางการ แต่การใช้ไวยากรณ์ที่ได้รับการปรับปรุงแก้ไขปัญหาได้แล้ว
stevenspiel

1
@ hurikhan77 ใช่มันไม่น่าเป็นไปได้ที่ไวยากรณ์ขัดแย้งกับ CoffeeScript coffeescript.org/#functions
Chloe

8

Rails 4 คุณสามารถ:

scope :find_lazy, -> (id) { where(id: id) }

นั่นคือทับทิมเก่า

:id => id

แฮชที่ดีกว่า:

id: id

5

คนที่แต่งตัวประหลาดฉันมักจะใช้ไวยากรณ์การเขียนโปรแกรมด้านล่าง

scope :find_lazy, -> (id) { where(id: id) }

แต่เมื่อฉันตรวจสอบรหัสของฉันโดยใช้ Codacy ฉันพบว่ามันแจ้งเตือนฉันเกี่ยวกับไวยากรณ์นี้

Use the `lambda` method for multiline lambdas.

ฉันเปลี่ยนเป็นและมันทำงานได้ดี

  scope :find_lazy, lambda {|id|
    where(id: id)
  }


1
scope :find_lazy, -> (id) { where(id: id) }

เทียบเท่ากับ

self.find_lazy(id)
  where(id: id)
end

ขึ้นอยู่กับทับทิมบนรางคู่มือ :Using a class method is the preferred way to accept arguments for scopes.

ไม่มีเหตุผลที่จะใช้ขอบเขตร่วมกับ lambdas ในการกำหนดวิธีการเรียน มันเป็นเรื่องของการตั้งค่าส่วนตัว แต่ถ้าคุณต้องการทำตามคำแนะนำคุณควรใช้วิธีการเรียนเมื่อมีข้อโต้แย้งที่เกี่ยวข้อง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.