【问题标题】:Scope with multiple where conditions based on multiple conditions基于多个条件的具有多个 where 条件的范围
【发布时间】:2018-02-28 13:31:04
【问题描述】:

有没有可能使用类似的东西

  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")
  }

如果我使用这个范围,只有最后一个是有效的。

例如:

  • state(["upcoming"]) -> 工作
  • state(["open"]) -> 未使用的地方
  • state(["deleted"], ["upcoming"]) -> 仅在使用即将到来的条件时使用

【问题讨论】:

    标签: ruby-on-rails ruby scope


    【解决方案1】:

    希望这能解决您的问题。

    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
    

    【讨论】:

    • 感谢您的想法。我认为当 state open 不包括在内时会出现问题,因为这样 select 将启动 win AND 子句。
    • 是的,我认为您需要添加一些条件来处理此问题。我只是展示了这样做的方法。
    【解决方案2】:

    你应该可以使用

      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
      }
    

    注意你应该这样做

    state(["deleted", "upcoming"])
    

    而不是

    state(["deleted"], ["upcoming"])
    

    您也可以使用Array.wrap 来简化作用域的使用:

      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
      }
    

    包装状态后,您可以通过以下两种方式使用范围:

    Model.state(['open', 'upcoming'])
    Model.state('open', 'upcoming')
    

    【讨论】:

    • 这对我不起作用。另外,我需要将条件与 OR 结合起来。我编辑了@Pardeep Saini 的答案,但他还不接受更改。
    猜你喜欢
    • 1970-01-01
    • 2014-10-11
    • 2015-02-14
    • 2021-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多