我想做的事情非常复杂,但请耐心等待。我正在使用Rails,ActiveRecord,Postgres。
活动有很多位置,有很多开始和结束时间。用户可以将自己分配给活动。
用户一次只能在一个地方。因此,在“将自己分配到活动页面”时,我只需要显示与用户已经分配的事件没有重叠时间的事件。
我知道你可以通过加入来做到这一点,但我无法弄清楚如何。
型号:
class Event < ActiveRecord::Base
has_many :locations
has_many :event_times
has_many :assignments
end
class Location < ActiveRecord::Base
belongs_to :event
has_many :event_times
end
class EventTime < ActiveRecord::Base
belongs_to :location
belongs_to :event
end
class User < ActiveRecord::Base
has_many :assignments
end
class Assignment < ActiveRecord::Base
belongs_to :user
belongs_to :event
end
总结了我正在努力做的事情。我知道这太糟糕了。
user_events = Assignment.where(user_id: current_user.id).pluck(:event_id)
blocked_event_times = EventTime.where(event_id: user_events)
blocked_query_string = ""
blocked_event_times.each do |bt|
blocked_query_string += "NOT( event_times.start <= '#{bt.end}'::timestamp AND event_times.end >= '#{bt.start}'::timestamp ) AND "
end
blocked_query_string += "1=1"
return Event.includes(:event_times).where(blocked_query_string).references(:event_times)
我是否在正确的轨道上认为我应该做一些像(伪代码)的事情:
@acceptable_times = EventTime.all LEFT JOIN user's_assigned_event_times
然后获取事件,其中所有事件的时间都出现在@acceptable_times
中答案 0 :(得分:0)
我不完全确定数据格式或EventTime模型是如何工作的,所以这是另一种基于Assignment
start_time
和end_time
以及start_time
的事件的解决方案{1}}和end_time
。
我猜你可以通过下面的例子传递EventTime
而不是Event
的实例。
def overlaps_existing_commitment?(event)
current_user.assignments.where("assignments.start_time < ? AND assignments.end_time > ?, event.start_time, event.end_time).any?
end
所以认为你可以循环事件:
events_to_render = []
@events.each do |event|
unless overlaps_existing_commitment?(event)
events_to_render << event
end
end
然后,您可以在视图中使用events_to_render
数组。
我相信有很多更好的方法,但希望能提供一些灵感来找到你满意的解决方案!
其他几件事:
我看得越多,我就越相信不需要EventTime模型。通过向其他模型添加start_time
和end_time
属性,它将使您的生活更轻松。
利用'?'在您的SQL查询中。