Вы можете сделать немного лучше, чем предлагал Адам Лассек, хотя он на правильном пути. Я только что решил похожую проблему, пытаясь получить список друзей из модели социальной сети. Друзья могут быть получены автоматически различными способами, но я хотел бы иметь дружественный метод запросов ActiveRelation, который может обрабатывать дальнейшие цепочки. Итак, у меня есть
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
, которая использует поддержку подзапросов Squeels. Сгенерированный SQL
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) ))
Альтернативный шаблон, в котором вам нужно переменное количество компонентов, демонстрируется с небольшим изменением вышеуказанного кода
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
А вот примерное решение относительно точного вопроса ОП
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