คุณทำor
แบบสอบถามในRails 5 ActiveRecord ได้อย่างไร? นอกจากนี้ยังสามารถเชื่อมโยงor
กับwhere
ในแบบสอบถาม ActiveRecord ได้หรือไม่
คุณทำor
แบบสอบถามในRails 5 ActiveRecord ได้อย่างไร? นอกจากนี้ยังสามารถเชื่อมโยงor
กับwhere
ในแบบสอบถาม ActiveRecord ได้หรือไม่
คำตอบ:
ความสามารถในการห่วงโซ่or
ข้อพร้อมกับwhere
ประโยคหนึ่งในActiveRecord
แบบสอบถามจะสามารถใช้ได้ในRails 5 ดูการอภิปรายที่เกี่ยวข้องและคำขอดึงการอภิปรายที่เกี่ยวข้องและขอดึง
ดังนั้นคุณจะสามารถทำสิ่งต่อไปนี้ในRails 5 :
ที่จะได้รับpost
มีid
1 หรือ 2:
Post.where('id = 1').or(Post.where('id = 2'))
ตัวอย่างอื่น ๆ :
(A && B) || ค:
Post.where(a).where(b).or(Post.where(c))
(A || B) && C:
Post.where(a).or(Post.where(b)).where(c)
Post.where(a).or(Post.where(b)).where(Post.where(c).or(Post.where(d)))
ควรจะสร้าง (a || b) && (c || d)
ArgumentError: Unsupported argument type: #<MyModel::ActiveRecord_Relation:0x00007f8edbc075a8> (MyModel::ActiveRecord_Relation)
(เพิ่มเติมจากคำตอบของ KM Rakibul Islam)
การใช้ขอบเขตรหัสจะสวยขึ้น (ขึ้นอยู่กับดวงตาที่มอง):
scope a, -> { where(a) }
scope b, -> { where(b) }
scope a_or_b, -> { a.or(b) }
ฉันต้องทำ (A && B) || (C && D) || (E && F)
แต่ใน Rails 5.1.4
สถานะปัจจุบันของสิ่งนี้ซับซ้อนเกินกว่าที่จะทำได้ด้วย Arel หรือ-chain แต่ฉันยังคงต้องการใช้ Rails เพื่อสร้างแบบสอบถามให้มากที่สุด
ดังนั้นฉันจึงทำการแฮ็กเล็ก ๆ :
ในโมเดลของฉันฉันสร้างเมธอดส่วนตัวที่เรียกว่าsql_where
:
private
def self.sql_where(*args)
sql = self.unscoped.where(*args).to_sql
match = sql.match(/WHERE\s(.*)$/)
"(#{match[1]})"
end
ถัดไปในขอบเขตของฉันฉันสร้างอาร์เรย์เพื่อเก็บ OR
scope :whatever, -> {
ors = []
ors << sql_where(A, B)
ors << sql_where(C, D)
ors << sql_where(E, F)
# Now just combine the stumps:
where(ors.join(' OR '))
}
ซึ่งจะให้ผลลัพธ์การค้นหาที่คาดหวัง:
SELECT * FROM `models` WHERE ((A AND B) OR (C AND D) OR (E AND F))
.
และตอนนี้ฉันสามารถรวมสิ่งนี้กับขอบเขตอื่น ๆ ได้อย่างง่ายดายโดยไม่ผิดพลาดหรือของ
ความสวยความงามเป็นที่ sql_where ของฉันใช้เวลาปกติที่ข้อโต้แย้งข้อ:
จะสร้างsql_where(name: 'John', role: 'admin')
(name = 'John' AND role = 'admin')
.merge
เทียบเท่ากับ && และสร้างต้นไม้ที่เหมาะสมเพื่อจับภาพ parens ของคุณ บางอย่าง ... (scopeA.merge(scopeB)).or(scopeC.merge(scopeD)).or(scopeE.merge(scopeF))
สมมติว่าแต่ละขอบเขตมีลักษณะเป็นModel.where(...)
ราง 5 มีความสามารถสำหรับประโยคที่มีor
where
ตัวอย่างเช่น.
User.where(name: "abc").or(User.where(name: "abcd"))