ruby on rails,chain命令用于过滤器

时间:2014-11-12 22:51:04

标签: ruby-on-rails ruby

一个小问题,我有一个显示即将发生的事件的命令,这很好用

@events = Event.where("startdate >= ?", Date.today).order("startdate, starttime")

现在我有一个过滤器,只选择一个目标组。比如男人,女人。

case params[:filter]
    when "Men" 
        @events = Event.men
    when "Women" 
        @events = Event.women 
    when "Juniors"
        @events = Event.juniors
    else
        @events = Event.all

问题是现在我想要结合这两个过滤器,更多的是我不需要重复'.where(...)'每一行。什么是解决这个问题的好方法。我是否需要更新我的范围,例如男人,女人,以便他们只显示即将发生的事件,或者我可以在控制器中解决这个问题吗?

干杯 莱尼

3 个答案:

答案 0 :(得分:2)

当您致电Event.men或其他范围时,不会立即对其进行评估。所以如果params[:filter] = 'Men',那么

case params[:filter]
    when "Men" 
        @events = Event.men
    when "Women" 
        @events = Event.women 
    when "Juniors"
        @events = Event.juniors
    else
        @events = Event.all
    end
@events = @events.where("startdate >= ?", Date.today).order("startdate, starttime")

将构建一个表达式:

@events = Event.men.where("startdate >= ?", Date.today).order("startdate, starttime")

只有这样才会从DB中获取。

答案 1 :(得分:1)

很难弄清楚Event.women会是什么,但我会假设事件表中有一些类型列。

在这种情况下,我会像这样在事件上创建一个方法:

def self.upcoming type
  Event.where("startdate >= ? and type = ?", Date.today, type).order("startdate, starttime")
end

并正确处理您的默认案例。将您的开关放在类方法中。在我看来,在控制器中有这个代码气味。

答案 2 :(得分:0)

这是ActiveRecord::Relation

@events = Event.where("startdate >= ?", Date.today)
               .order("startdate, starttime")

仍然是潜在的条件链,直到某些东西强迫它成为具体

这意味着您可以继续为@events关系添加条件,就像在Felix的答案中一样。

就个人而言,我喜欢用私有方法提取这种逻辑:

class MyController < ApplicationController

  def index
    @events = Event.where("startdate >= ?", Date.today)
                   .order("startdate, starttime")

    @events = apply_type_filter(@events)
  end


private


  def apply_type_filter(relation)
    case params[:filter]
    when "Men" 
      relation.men
    when "Women" 
      relation.women 
    when "Juniors"
      relation.juniors
    else
      relation
    end
  end

end