Is there possible to use something like
scope :state, ->(state) {
merge(where("start_time <= ? and end_time >= ?", Time.now.utc.beginning_of_day, Time.now.utc.beginning_of_day)) if state.include?("open")
merge(where("end_time < ?", Time.now.utc.beginning_of_day)) if state.include?("closed")
merge(where("start_time > ?", Time.now.utc.beginning_of_day)) if state.include?("upcoming")
}
If I use this scope, only the last one is functional.
for example:
- state(["upcoming"]) -> work
- state(["open"]) -> where is not used
- state(["deleted"], ["upcoming"]) -> only where with upcoming conditions is used
hope this solve your problem.
scope :state, ->(state) {where(self.query_conditions(state), q: Time.now.utc.beginning_of_day))}
def self.query_conditions(state)
q = ""
q+= "start_time <= :q and end_time >= :q" if state.include?("open")
q+= " and end_time < :q" if state.include?("closed")
q+= " and start_time > :q" if state.include?("upcoming")
q
end
You should be able to use
scope :state, ->(state) {
rel = all
rel = rel.where("start_time <= ? and end_time >= ?", Time.now.utc.beginning_of_day, Time.now.utc.beginning_of_day) if state.include?("open")
rel = rel.where("end_time < ?", Time.now.utc.beginning_of_day) if state.include?("closed")
rel = rel.where("start_time > ?", Time.now.utc.beginning_of_day) if state.include?("upcoming")
rel
}
Notice that you should do
state(["deleted", "upcoming"])
instead of
state(["deleted"], ["upcoming"])
Also you can use Array.wrap to simplify using the scope:
scope :state, ->(state) {
state = Array.wrap(state)
rel = all
rel = rel.where("start_time <= ? and end_time >= ?", Time.now.utc.beginning_of_day, Time.now.utc.beginning_of_day) if state.include?("open")
rel = rel.where("end_time < ?", Time.now.utc.beginning_of_day) if state.include?("closed")
rel = rel.where("start_time > ?", Time.now.utc.beginning_of_day) if state.include?("upcoming")
rel
}
With state being wrapped you can use the scope in both following ways:
Model.state(['open', 'upcoming'])
Model.state('open', 'upcoming')