คุณจะทำการสืบค้น OR ใน Rails 3 ActiveRecord ได้อย่างไร ตัวอย่างทั้งหมดที่ฉันพบมีเพียงแบบสอบถาม
แก้ไข: หรือวิธีนี้มีให้ตั้งแต่ Rails 5. ดูActiveRecord :: QueryMethods
Post.where(column: 'something').or(Post.where(other: 'else'))
คุณจะทำการสืบค้น OR ใน Rails 3 ActiveRecord ได้อย่างไร ตัวอย่างทั้งหมดที่ฉันพบมีเพียงแบบสอบถาม
แก้ไข: หรือวิธีนี้มีให้ตั้งแต่ Rails 5. ดูActiveRecord :: QueryMethods
Post.where(column: 'something').or(Post.where(other: 'else'))
คำตอบ:
ใช้ARel
t = Post.arel_table
results = Post.where(
t[:author].eq("Someone").
or(t[:title].matches("%something%"))
)
ผลลัพธ์ SQL:
ree-1.8.7-2010.02 > puts Post.where(t[:author].eq("Someone").or(t[:title].matches("%something%"))).to_sql
SELECT "posts".* FROM "posts" WHERE (("posts"."author" = 'Someone' OR "posts"."title" LIKE '%something%'))
matches
จะสร้างLIKE
สำหรับ sqlite (case insensitive โดยค่าเริ่มต้น) และILIKE
postgres (ต้องการ case insensitive ที่ชัดเจนเช่นโอเปอเรเตอร์)
หากคุณต้องการใช้ตัวดำเนินการ OR กับค่าของคอลัมน์หนึ่งคุณสามารถส่งอาร์เรย์ไปยัง.where
และ ActiveRecord จะใช้IN(value,other_value)
:
Model.where(:column => ["value", "other_value"]
เอาท์พุท:
SELECT `table_name`.* FROM `table_name` WHERE `table_name`.`column` IN ('value', 'other_value')
สิ่งนี้ควรบรรลุความเท่าเทียมกันของOR
หนึ่งคอลัมน์
ใน Rails 3 ควรเป็น
Model.where("column = ? or other_column = ?", value, other_value)
นอกจากนี้ยังรวมถึง sql ดิบ แต่ฉันไม่คิดว่ามีวิธีใน ActiveRecord ที่จะทำหรือดำเนินการ คำถามของคุณไม่ใช่คำถาม noob
Page.where("pages.column = ? or pages.other_column = ?", value, other_value)
Rails / ActiveRecord รุ่นที่ปรับปรุงแล้วอาจรองรับไวยากรณ์นี้ได้ มันจะมีลักษณะคล้ายกับ:
Foo.where(foo: 'bar').or.where(bar: 'bar')
ตามที่ระบุไว้ในคำขอดึงนี้https://github.com/rails/rails/pull/9052
สำหรับตอนนี้เพียงแค่ติดกับงานต่อไปนี้ได้ดี:
Foo.where('foo= ? OR bar= ?', 'bar', 'bar')
ปรับปรุง:ตามhttps://github.com/rails/rails/pull/16052or
คุณลักษณะจะสามารถใช้ได้ใน Rails 5
อัพเดท:ฟีเจอร์ถูกรวมเข้ากับ Rails 5 branch
or
ใช้งานได้แล้วตอนนี้ Rails 5 แต่ไม่สามารถใช้งานได้เนื่องจากคาดว่าจะมีการส่งอาร์กิวเมนต์ 1 รายการ มันคาดว่าวัตถุ Arel ดูคำตอบที่ยอมรับ
or
วิธีการใน ActiveRecord ทำงานหากคุณกำลังใช้โดยตรง แต่สามารถทำลายความคาดหวังของคุณถ้ามันใช้อยู่ในขอบเขตซึ่งเป็นที่ถูกล่ามโซ่แล้ว
Rails ได้เพิ่มสิ่งนี้ลงใน ActiveRecord ดูเหมือนว่าจะเปิดตัวใน Rails 5 มุ่งมั่นที่จะโทแล้ว:
https://github.com/rails/rails/commit/9e42cf019f2417473e7dcbfcb885709fa2709f89
Post.where(column: 'something').or(Post.where(other: 'else'))
# => SELECT * FROM posts WHERE (column = 'something') OR (other = 'else)
Rails 5 มาพร้อมกับor
วิธีการ (l หมึกเอกสาร )
วิธีนี้ยอมรับActiveRecord::Relation
วัตถุ เช่น:
User.where(first_name: 'James').or(User.where(last_name: 'Scott'))
หากคุณต้องการใช้อาร์เรย์เป็นอาร์กิวเมนต์รหัสต่อไปนี้จะทำงานใน Rails 4:
query = Order.where(uuid: uuids, id: ids)
Order.where(query.where_values.map(&:to_sql).join(" OR "))
#=> Order Load (0.7ms) SELECT "orders".* FROM "orders" WHERE ("orders"."uuid" IN ('5459eed8350e1b472bfee48375034103', '21313213jkads', '43ujrefdk2384us') OR "orders"."id" IN (2, 3, 4))
ข้อมูลเพิ่มเติม: หรือแบบสอบถามกับอาร์เรย์เป็นข้อโต้แย้งในทางรถไฟ 4
Order.where(query.where_values.inject(:or))
การใช้ arel ตลอดทาง
MetaWhereปลั๊กอินเป็นที่น่าตื่นตาตื่นใจอย่างสมบูรณ์
ผสม OR หรือ AND และร่วมกับเงื่อนไขในการเชื่อมโยงใด ๆ ได้อย่างง่ายดายและยังระบุ OUTER JOIN ของ!
Post.where({sharing_level: Post::Sharing[:everyone]} | ({sharing_level: Post::Sharing[:friends]} & {user: {followers: current_user} }).joins(:user.outer => :followers.outer}
เพียงเพิ่มหรือในเงื่อนไข
Model.find(:all, :conditions => ["column = ? OR other_column = ?",value, other_value])
ฉันเพิ่งแยกปลั๊กอินนี้จากงานลูกค้าที่ให้คุณรวมขอบเขตกับ.or.
, ex. Post.published.or.authored_by(current_user)
. Squeel (การใช้ MetaSearch รุ่นใหม่กว่า) นั้นยอดเยี่ยมเช่นกัน แต่ไม่อนุญาตให้คุณหรือขอบเขตดังนั้นตรรกะการสืบค้นจึงสามารถซ้ำซ้อนได้เล็กน้อย
ด้วย Rails + arel วิธีที่ชัดเจนยิ่งขึ้น:
# Table name: messages
#
# sender_id: integer
# recipient_id: integer
# content: text
class Message < ActiveRecord::Base
scope :by_participant, ->(user_id) do
left = arel_table[:sender_id].eq(user_id)
right = arel_table[:recipient_id].eq(user_id)
where(Arel::Nodes::Or.new(left, right))
end
end
ผลิต:
$ Message.by_participant(User.first.id).to_sql
=> SELECT `messages`.*
FROM `messages`
WHERE `messages`.`sender_id` = 1
OR `messages`.`recipient_id` = 1
คุณสามารถทำได้เช่น:
Person.where("name = ? OR age = ?", 'Pearl', 24)
หรือมากกว่านั้นให้ติดตั้งrails_or gem และทำเช่น:
Person.where(:name => 'Pearl').or(:age => 24)
ฉันต้องการเพิ่มสิ่งนี้เป็นวิธีแก้ปัญหาเพื่อค้นหาคุณลักษณะหลายอย่างของ ActiveRecord ตั้งแต่
.where(A: param[:A], B: param[:B])
จะค้นหา A และ B
Book.where.any_of(Book.where(:author => 'Poe'), Book.where(:author => 'Hemingway')