Scope with multiple where conditions based on multiple conditions

心已入冬 提交于 2020-01-16 12:33:24

问题


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

回答1:


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



回答2:


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')


来源:https://stackoverflow.com/questions/49030775/scope-with-multiple-where-conditions-based-on-multiple-conditions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!