Это меня поставило в тупик, так что я надеюсь, что тот, кто умнее меня, сможет мне помочь.
Я работаю над проектом rails, в котором у меня есть модель User, к которой присоединена ассоциация clock_periods, имеющая следующее частичное определение:
User
has_many :clock_periods
#clock_periods has the following properties:
#clock_in_time:datetime
#clock_out_time:datetime
named_scope :clocked_in, :select => "users.*",
:joins => :clock_periods, :conditions => 'clock_periods.clock_out_time IS NULL'
def clocked_in?
#default scope on clock periods sorts by date
clock_periods.last.clock_out_time.nil?
end
SQL-запрос для извлечения всех синхронизированных пользователей тривиален:
SELECT users.* FROM users INNER JOIN clock_periods ON clock_periods.user_id = users.id
WHERE clock_periods.clock_out_time IS NULL
Однако обратное - найти всех пользователей, которые в данный момент отключены, - обманчиво сложно. Я закончил тем, что использовал следующее именованное определение области действия, хотя оно и хакерское:
named_scope :clocked_out, lambda{{
:conditions => ["users.id not in (?)", clocked_in.map(&:id)+ [-1]]
}}
Что меня беспокоит, так это то, что, похоже, должен быть способ сделать это в SQL, не прибегая к генерации операторов вроде
SELECT users.* FROM users WHERE users.id NOT IN (1,3,5)
У кого-нибудь есть способ получше, или это действительно единственный способ справиться с этим?