具有多个条件的范围基于多个条件的条件

时间:2018-02-28 13:31:05

标签: ruby-on-rails ruby scope

是否可以使用

之类的东西
  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")
  }

如果我使用此范围,则只有最后一个范围可用。

例如:

  • 州([&#34;即将到来&#34;]) - &gt;工作
  • 州([&#34; open&#34;]) - &gt;哪里没用过
  • 州([&#34;已删除&#34;],[&#34;即将推出&#34;]) - &gt;只有在即将使用条件的地方

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

你应该可以使用

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