Ruby on Rails - 针对相同数据的两个不同过滤器

时间:2017-04-19 11:10:32

标签: javascript ruby-on-rails ruby view filter

在主页面上,我有一个视频和图片列表。那些视频&图片属于某个类别。所以,我有一个类别的过滤器和一个类型(vidéos或图片)。问题是我不能在不改变第一个过滤器的情况下同时使用两个过滤器。例如,如果我只想显示图片,然后我想要一个特定类别,我会从所选类别中获取所有图片和视频
例如图片过滤器:
view / galeries / index.html.erb

<%= link_to show_pictures_path, :remote => true, :id => "btn-pictures", :class => "btn btn-default" do %>
<em class="glyphicon glyphicon-picture"></em> Pictures
<% end %>

控制器/ galeries_controller.rb

  def show_pictures
    @selected = Picture.order('created_at DESC')
  end

查看/老佛爷/ show_pictures.js.erb

$("#media_filter").html("<%= escape_javascript(render partial: 'partials/media_filter', locals: { medias: @selected } ) %>");

左编辑 - 类别的例子:
视图/老佛爷/ index.html.erb

<% @categories.each do |c| %>
  <li class="" id=btn-filter<%=c.id%>>
    <%= link_to show_categories_path(:id => c.id), :remote => true do %>
    <span class="badge pull-right"><%= Media.joins(:pictures).where(category_id: c.id).count + Media.joins(:videos).where(category_id: c.id).count  %></span> <%= c.name %>
    <% end %>
  </li>
<% end %>

控制器/ galeries_controller.rb

  def show_categories
   @videos = Video.joins(:media).where("medium.category_id = ?", params[:id])
   @pictures = Picture.joins(:media).where("medium.category_id = ?", params[:id])
  end

查看/老佛爷/ show_categories.js.erb

$("#media_filter").html("<%= escape_javascript(render partial: 'partials/media_filter', locals: { medias: @videos} ) %>"); 
$("#media_filter").append("<%= escape_javascript(render partial: 'partials/media_filter', locals: { medias: @pictures } ) %>");

3 个答案:

答案 0 :(得分:2)

  def show_categories
     if selected_videos == true
      @videos = Video.joins(:media).where("medium.category_id = ?", params[:id])
     else
      @videos = [] # not the most clean but a way is to pass an empty array...
     end
     if selected_pictures == true
       @pictures = Picture.joins(:media).where("medium.category_id = ?", params[:id])
     else
      @pictures = [] # the same, empty array...
    end
  end

现在您只需传递类似复选框的内容即可启用内容

答案 1 :(得分:2)

如果您已创建搜索form_tag

只需为每种类型添加切换表单/复选框,然后在控制器中添加条件

def show_categories
  @pictures = Picture.joins(:media).where("medium.category_id = ?", params[:category]) if params[:picture]=='true'   
  @videos = Video.joins(:media).where("medium.category_id = ?", params[:category]) if params[:video]=='true'
end

我预计网址会像这样

yourhostname/yourmodels?utf8=✓&picture=boolean&video=boolean&category=integer

答案 2 :(得分:1)

如果我理解正确,问题似乎是您的应用不会记住之前过滤器的值。

您可以通过将选定的过滤器作为参数发送并将其添加到链接来模拟此操作,因此下一个请求将获得前一个过滤器的值(如果有)。

无需使用单独的操作,只需在控制器中执行一个操作即可应用过滤器(我在示例中使用了show_media),您只需要检查params以显示正确的信息。

# controller/galeries_controller.rb

def show_media
  @category = params[:category]
  @type     = params[:type]
  @pictures = media(Picture) if @type == "pictures"
  @videos   = media(Video) if @type == "videos"
end

private
def media(model)
  if @category.blank?
    model.order('created_at DESC')
  else
    model.joins(:media).where("medium.category_id = ?", params[:id])
  end
end

您要设置@pictues@videos的值,但不要使用两个操作,只需检查type即可设置其中一个。

方法media接收要使用的模型对象(VideoPicture),并根据是否提供category返回相关的模型记录(这有助于你稍微干了你的代码。

接下来,您必须更新链接以同时包含typecategory,这需要在index.html.erbshow_media.js.erb中完成:

# index.html.erb

<%= link_to show_media_path(type: "pictures"), remote: true, id: "btn-pictures", class: "btn btn-default" do %>
    <em class="glyphicon glyphicon-picture"></em> Pictures
<% end %>

<%= link_to show_media_path(type: "videos"), remote: true, id: "btn-videos", class: "btn btn-default" do %>
    <em class="glyphicon glyphicon-video"></em> Videos
<% end %>

<% @categories.each do |c| %>
  <li class="" id="btn-filter<%= c.id %>">
    <%= link_to show_categories_path(id: c.id), remote: true, "data-category-id": c.id, class: "category-id" do %>
    <span class="badge pull-right"><%= Media.joins(:pictures).where(category_id: c.id).count + Media.joins(:videos).where(category_id: c.id).count  %></span> <%= c.name %>
    <% end %>
  </li>
<% end %>

我们将type添加到了picturesvideos(没有category,因为还没有选择),以及一些属性(data-category-id和{{ 1}})到您的类别链接,以便能够在class上识别它们。

show_media.js.erb

添加的行将修改您的链接,以包含# show_media.js.erb $("#media_filter").html("<%= escape_javascript(render partial: 'partials/media_filter', locals: { medias: @videos} ) %>"); $("#media_filter").append("<%= escape_javascript(render partial: 'partials/media_filter', locals: { medias: @pictures } ) %>"); $(#'btn-pictures').attr('href',"<%= show_media_path(type: 'pictures', category: @category) %>"); $(#'btn-videos').attr('href',"<%= show_media_path(type: 'pictures', category: @category) %>"); $('.category-id').each(function() { $(this).attr("href", "/show_media?type=<%= @type %>" + "&category=" + $(this).attr("data-category-id"); }); type参数,具体取决于您之前的请求,使用您在{1}}创建的category@category变量控制器。

现在,无论您先点击什么,您都会将正确选择的过滤器传递给您的控制器,而不会每次都丢失它们。