Bạn có thể làm tốt hơn một chút so với những gì Adam Lassek đã đề xuất mặc dù anh ấy đi đúng hướng. Tôi vừa giải quyết một vấn đề tương tự khi cố gắng lấy danh sách bạn bè từ một mô hình mạng xã hội. Bạn bè có thể được mua tự động theo nhiều cách khác nhau nhưng tôi muốn có một phương thức truy vấn thân thiện với ActiveRelation có thể xử lý chuỗi tiếp theo. Vì vậy, tôi có
class User
has_many :events_as_owner, :class_name => "Event", :inverse_of => :owner, :foreign_key => :owner_id, :dependent => :destroy
has_many :events_as_guest, :through => :invitations, :source => :event
def friends
friends_as_guests = User.joins{events_as_guest}.where{events_as_guest.owner_id==my{id}}
friends_as_hosts = User.joins{events_as_owner}.joins{invitations}.where{invitations.user_id==my{id}}
User.where do
(id.in friends_as_guests.select{id}
) |
(id.in friends_as_hosts.select{id}
)
end
end
end
lợi dụng hỗ trợ truy vấn con của Squeel. SQL được tạo ra là
SELECT "users".*
FROM "users"
WHERE (("users"."id" IN (SELECT "users"."id"
FROM "users"
INNER JOIN "invitations"
ON "invitations"."user_id" = "users"."id"
INNER JOIN "events"
ON "events"."id" = "invitations"."event_id"
WHERE "events"."owner_id" = 87)
OR "users"."id" IN (SELECT "users"."id"
FROM "users"
INNER JOIN "events"
ON "events"."owner_id" = "users"."id"
INNER JOIN "invitations"
ON "invitations"."user_id" =
"users"."id"
WHERE "invitations"."user_id" = 87)))
Một mô hình thay thế mà bạn cần có một số biến của các thành phần được thể hiện với một sửa đổi nhỏ vào mã ở trên
def friends
friends_as_guests = User.joins{events_as_guest}.where{events_as_guest.owner_id==my{id}}
friends_as_hosts = User.joins{events_as_owner}.joins{invitations}.where{invitations.user_id==my{id}}
components = [friends_as_guests, friends_as_hosts]
User.where do
components = components.map { |c| id.in c.select{id} }
components.inject do |s, i|
s | i
end
end
end
Và đây là một rough đoán như các giải pháp cho các câu hỏi chính xác OP của
class Shift < ActiveRecord::Base
def self.limit_per_day(options = {})
options[:start] ||= Date.today
options[:stop] ||= Date.today.next_month
options[:per_day] ||= 5
queries = (options[:start]..options[:stop]).map do |day|
where{|s| s.scheduled_start >= day}.
where{|s| s.scheduled_start < day.tomorrow}.
limit(options[:per_day])
end
where do
queries.map { |c| id.in c.select{id} }.inject do |s, i|
s | i
end
end
end
end
Tuy nhiên, đây là trường hợp hơi khác. Tôi cần để có thể chuỗi một số tùy ý của các lựa chọn với nhau. Vì vậy, tôi vẫn sẽ phải sử dụng đến nội suy chuỗi bất kể tôi có sử dụng 'UNION' hay' OR' hay không. Trừ khi bạn có thể đề xuất một cách để thực hiện điều đó với Squeel/AREL? –
Điều đó có thể được thực hiện. Nó chỉ đòi hỏi một chút ma thuật. Để tôi nghi vê no. Có lẽ có thể được thực hiện với Enumerable tiêm. Tôi sẽ cung cấp cho nó một đi và cập nhật câu trả lời nếu nó hoạt động. – bradgonesurfing
Ok. Tôi đã thực hiện một hàm tương đương để đặt các thành phần vào một mảng đầu tiên và sau đó kết hợp các thành phần đó.Chỉ cần nhớ rằng SQueel chỉ đơn giản là ruby với một số phương pháp thiếu phép thuật. Bạn có thể làm ruby bình thường bên trong khối và xây dựng truy vấn động. – bradgonesurfing