Ruby on Rails - 在视图中为同一数据使用两个不同的过滤器

16 浏览
0 Comments

Ruby on Rails - 在视图中为同一数据使用两个不同的过滤器

在主页面上,我有一个视频和图片的列表。这些视频和图片属于一个类别。因此,我有一个用于类别的过滤器和一个用于类型(视频或图片)的过滤器。问题是,我不能同时使用这两个过滤器,而不改变第一个过滤器。例如,如果我只想显示图片,然后想要一个特定的类别,我会得到所选类别的所有图片和视频。示例中的图片过滤器:
查看/galeries/index.html.erb

<%= link_to show_pictures_path, :remote => true, :id => "btn-pictures", :class => "btn btn-default" do %>
 图片
<% end %>

controller/galeries_controller.rb

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

view/galeries/show_pictures.js.erb

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

编辑-类别示例:

view/galeries/index.html.erb

<% @categories.each do |c| %>
  
  • > <%= link_to show_categories_path(:id => c.id), :remote => true do %> <%= Media.joins(:pictures).where(category_id: c.id).count + Media.joins(:videos).where(category_id: c.id).count %> <%= c.name %> <% end %>
  • <% end %>

    controller/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
    

    view/galeries/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 } ) %>");
    

    0
    0 Comments

    问题的原因是应用程序没有记住之前筛选器的值。解决方法是通过将所选的筛选器作为参数发送,并将它们添加到链接中,以便下一次请求能够获取先前筛选器的值(如果有的话)。不需要使用单独的动作,可以在控制器中的一个动作中应用筛选器(在示例中使用了show_media),只需要检查params以显示正确的信息。

    在控制器galeries_controller.rb中设置categorytype的值,但不需要使用两个动作,只需检查type以设置其中一个值。方法media接收要使用的模型对象(VideoPicture)并根据是否提供category返回相关的模型记录(这有助于使代码更加简洁)。

    接下来,必须更新链接以包括typecategory,这需要在index.html.erbshow_media.js.erb中完成。

    index.html.erb中,添加typepicturesvideos(没有category因为还没有选择),并在类别链接中添加了一对属性(data-category-idclass)以便在show_media.js.erb中识别它们。

    show_media.js.erb中,添加的代码将根据之前的请求修改链接,根据控制器中创建的typecategory变量来包含typecategory参数。

    现在,无论首先点击什么,都将始终将正确的选定筛选器传递给控制器,而不会每次都丢失它们。

    0
    0 Comments

    在这个问题中,出现的原因是需要在视图中为相同的数据添加两个不同的过滤器。解决方法是在控制器中添加条件,并在视图中添加一个切换表单/复选框来控制过滤器的类型。

    首先,在视图中创建一个搜索表单,然后为每种类型添加一个切换表单/复选框。然后,在控制器中添加条件来根据选择的过滤器类型查询数据。以下是示例代码:

    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
    

    期望的URL应该像这样:

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

    所以,使用这个解决方案,我需要用复选框替换link_to吗?你仍然可以使用link_to/button,但不要忘记将参数发送到控制器。你可以参考这个stackoverflow的链接来了解如何添加查询字符串参数到link_to:[add querystring parameters to link to](http://stackoverflow.com/questions/2695538)

    在控制器中,你可以使用params[:video]和params[:picture]来获取过滤器的值。

    0
    0 Comments

    这段代码中存在一个问题,即在视图中为相同的数据使用了两个不同的过滤器。这个问题的出现原因是在show_categories方法中,使用了两个条件语句来判断是否选中了视频和图片。

    解决这个问题的方法是去除多余的条件判断语句。可以通过将两个条件合并为一个条件来实现。具体做法是使用一个变量来存储过滤条件,并在查询中使用这个变量。这样可以避免重复的代码和条件判断。

    下面是修改后的代码:

    def show_categories
      selected = params[:selected] # 获取选中的过滤条件,可以是视频或图片
      if selected.present?
        = Medium.joins(:category).where("category.id = ? AND medium.type = ?", params[:id], selected)
      else
        = [] # 如果没有选中过滤条件,返回一个空数组
      end
    end

    现在只需要传递一个类似复选框的参数来启用内容过滤。这样就解决了问题,并且代码更加简洁和易读。

    0