Rails:搜索过滤

时间:2019-06-10 10:46:13

标签: ruby-on-rails filtering advanced-search

请,我需要一些有关正在从事的数字图书馆项目的帮助。我想向该应用程序添加一些搜索过滤功能。

该应用程序主要具有属于子类别的书籍和属于类别的子类别。

我想创建一个搜索过滤功能,当您搜索特定书籍时,您可以根据书籍的类别过滤书籍。

因此,首先创建类别,然后创建子类别,然后选择这些子类别所属的类别,然后创建书籍,然后仅选择每本书所属的类别,这将自动将该书籍置于类别中该子类别所属的类别。

目前,仅当我将类别添加到图书新表格时,搜索过滤器才起作用。那就是如果我修改书籍的新表格,然后在表格中包括类别选择。但我只想在新表格中仅包含子类别,因为每个子类别已经属于一个类别。

代码如下

图书模型

class Subcategory < ApplicationRecord
  belongs_to :category
  has_many :books
end

子类别模型

class Category < ApplicationRecord
  has_many :subcategories
  has_many :books
end

类别模型

class BooksController < ApplicationController
  before_action :set_book, only: [:show, :edit, :update, :destroy]

  def index
    if params[:category].blank? or params[:category][:id].blank? 
      @books_view = Book.all
    else  
      @books_view = Category.find(params[:category][:id]).books
    end
    @books = @books_view.search(params[:keywords]).paginate(page: params[:page], per_page: 12)
  end
end

Books Controller(截断)

<%= form_tag(books_path, method: :get) do %>
      <%= text_field_tag :keywords, params[:keywords], {placeholder: 'eg: Nursing', :class => 'searchForm'} %>
      <%= collection_select :category, :id, Category.all.order('name ASC'), :id, :name,{include_blank: 'Select Category'}, { :class => 'form-control'} %>
    <button type="submit">
      Search
      <%= image_tag("searchIcon.svg", :alt => "search", :class => "") %>
    </button>
  <% end %>

图书索引页搜索表单

class BooksController < ApplicationController
    before_action :set_book, only: [:show, :edit, :update, :destroy]

    def index
        if params[:category].blank? or params[:category][:id].blank? 
            @books_view = Book.all
        else  
            @books_view = Book.joins(:subcatagory).joins('catagories on catagories.id = subcatagories.catagory_id').where(catagories: {id: params[:catagory][:id]})
        end
        @books = @books_view.search(params[:keywords]).paginate(page: params[:page], per_page: 12)
    end
end 

请帮助我。我们将不胜感激。谢谢。

更新

通过 Books Controller 这样的更新方式,我尝试了 Dileep Nandanam 的解决方案

{{1}}

但是它确实没有按预期工作。我遇到了一些问题。下面是该问题的屏幕截图。

![NoMethodError in BooksController#index undefined method `[]' for nil:NilClass] 1

2 个答案:

答案 0 :(得分:0)

我相信您的问题来自于此特定问题:

class Book < ApplicationRecord
  belongs_to :category, required: false # <= This is wrong
  belongs_to :subcategory, required: false
end

您的特定问题的答案是:

<%= form_tag(books_path, method: :get) do %>
      <%= text_field_tag :keywords, params[:keywords], {placeholder: 'eg: Nursing', :class => 'searchForm'} %>
      <%= collection_select :subcategory, :id, Subcategory.all.order('name ASC'), :id, :name,{include_blank: 'Select Category'}, { :class => 'form-control'} %>
    <button type="submit">
      Search
      <%= image_tag("searchIcon.svg", :alt => "search", :class => "") %>
    </button>
  <% end %>

但是让我们详细说明答案:

看,您的抽象中有一个大问题。如果一本书既属于子类别(带有subcategory_id)又属于类别(带有category_id),那么您实际上就没有一致的数据结构。如果使用关系数据库,则违反了数据库规范化。 这里真正应该发生的是将Book中的Category拆分并通过Subcategory进行引用,如下所示:

class Book < ApplicationRecord
  belongs_to :category, required: false, through: :subcategory
  belongs_to :subcategory, required: false
end

答案 1 :(得分:0)

请严格存储category_id在子类别中和subcatagory_id在书籍中,而不是catagory_id在书籍中。

我们以此方式稍微修改了索引操作

class BooksController < ApplicationController
    before_action :set_book, only: [:show, :edit, :update, :destroy]

    def index
        if params[:category].blank? or params[:category][:id].blank? 
            @books_view = Book.all
        else  
            @books_view = Book.joins(:subcatagory).joins('catagories on catagories.id = subcatagories.catagory_id').where(catagories: {id: params[:catagory][:id]})
        end
        @books = @books_view.search(params[:keywords]).paginate(page: params[:page], per_page: 12)
    end
end

搜索方法变为

def self.search(keywords)
    if keywords
        where('books.name LIKE ? OR book.description LIKE ? OR book.author LIKE ? OR book.abstract LIKE ?', "%#{keywords}%", "%#{keywords}%", "%#{keywords}%", "%#{keywords}%").order('books.id DESC')
    else
        order('books.id DESC')
    end
end