以正确的方式过滤非活动记录模型

时间:2016-04-09 12:18:50

标签: ruby-on-rails-4 activerecord

所以我有一个api,我可以查询并返回结果列表。我的应用程序然后将结果处理为像数组中的对象一样的activerecord。我在整个视图中显示这些对象,但我也想过滤掉结果。

这样做的最佳方式是什么?

目前,我正在做这样的事情:

查看

= form_tag path(resource), method: :get, class: "form-inline", role: "form" do
 .col-sm-3
   = label_tag "See unlimited usage only?"
   .clearfix
   = select_tag "usage", options_for_select(resource.class::USAGE, params[:usage]), class: "form-control", prompt: "All usage limits"

控制器

def show
  @media_deals = resource.media_deals
  if params[:usage].present?
    filter = params[:usage]
    if filter == "unlimited"
      @media_deals = @media_deals.find_all{|d| d.download_limit_display.casecmp("Unlimited") == 0}
    elsif filter == "limited"
      @media_deals = @media_deals.find_all{|d| d.download_limit_display.casecmp("Unlimited") != 0}
    end
  end
end

请记住,不仅仅会显示一个过滤器。

1 个答案:

答案 0 :(得分:0)

好吧,到目前为止,你做得很好,这样做没什么不对,但我有一些关于如何让它变得更好的建议。 首先,特别是如果您打算使用多个过滤器,请在Proc中对其进行整理。像这样举例如:

{
  unlimited: Proc.new {|d| d.download_limit_display.casecmp("Unlimited") == 0},
  limited: Proc.new {|d| d.download_limit_display.casecmp("Unlimited") != 0}
}

通过这种方式,您可以将所有过滤器放在一个位置并根据您需要的方式收集它们,然后按照each循环进行:

filters.each {|filter| @media_deals.find_all! &filter}

<强>更新

好的,所以对于整个周期。以下是您的观点的样子。

= form_tag path(resource), method: :get, class: "form-inline", role: "form" do
  .col-sm-3
    = label_tag "See unlimited usage only?"
     .clearfix
     = select_tag "filters[usage]", options_for_select(resource.class::USAGE, params[:filters][:usage] if params[:filters].present?)), class: "form-control", prompt: "All usage limits"
  .col-sm-3
    = label_tag "Filter by date"
     .clearfix
     = select_tag "filters[usage]", options_for_select(resource.class::USAGE, params[:filters][:usage] if params[:filters].present?)), class: "form-control", prompt: "All dates"

这是你的控制器。

def show
  @media_deals = resource.media_deals
  filters.each {|filter| @media_deals.select! &filter} if params[:filters].present?
end

private 

def all_filters
  {
    unlimited: Proc.new {|d| d.download_limit_display.casecmp("Unlimited") == 0},
    limited: Proc.new {|d| d.download_limit_display.casecmp("Unlimited") != 0},
    newest: Proc.new {|d| d.created_at <= 1.day.ago },
    recent: Proc.new {|d| d.created_at <= 4.days.ago },
    oldest: Proc.new {|d| d.created_at > 1.year.ago }
  }
end

def filters
  params[:filters].values.map {|f| all_filters[f] if f}.select &:present?
end 

只是为了让您了解正在发生的事情。我建议更进一步,将那组过滤器(all_filters方法)移动到资源本身,如果命名变得混乱,可能会将其分解为散列哈希值。