Rails:使用复选框过滤ActiveRecord搜索结果

时间:2016-09-24 19:31:25

标签: ruby-on-rails activerecord

我正在尝试构建一个复选框过滤器,它会减少检查每个框的结果数量。每个复选框将代表has_many:through关联。

我有一个有三个型号的应用程序: 书 学科 BookSubject

他们是这样关联的:

class Book < ActiveRecord::Base
  has_many :book_subjects
  has_many :subjects, through: :book_subjects
end

class Subject < ActiveRecord::Base
  has_many :book_subjects
  has_many :books, through: :book_subjects
end

class BookSubject < ActiveRecord::Base
  belongs_to :book
  belongs_to :subject
end

通过Books控制器,用户可以运行“搜索”操作,该操作将呈现包含所有书籍的视图页面。通过选中侧栏中的框(每个框都标有主题名称),用户应该能够缩小适合其搜索的书籍数量。这是迄今为止的搜索操作:

def search
  if params[:name].nil? || params[:name].empty?
    @all_books = Book.all
  else
    @all_books = Book.joins(:subjects).where(subjects: {name: params[:name].split(",")}).distinct
  end
  render 'search'
end

现在,如果用户选择“历史”和“史诗”,他们会获得所有以历史为主题的书籍,以及所有以史诗为主题的书籍。我希望他们只获得历史和史诗作为主题的书籍。我已经尝试将.group添加到查询中,但到目前为止它还没有工作:

def search
  if params[:name].nil? || params[:name].empty?
    @all_books = Book.all
  else
    @all_books = Book.joins(:subjects)
      .where(subjects: {name: params[:name].split(",")})
      .group("books.id")
      .having("count(*) >= ?", 1)
    end
  end
end

我应该如何修改查询以使过滤成为可能?谢谢!!!

1 个答案:

答案 0 :(得分:1)

我认为你的代码几乎没问题,但为什么你有having("count(*) >= ?", 1)? 该条件匹配所有必需列表中只有一个主题的书籍 尝试将代码更改为以下

def search
  @all_books = if params[:name].blank?
    Book.all
  else
    names = params[:name].split(',')
    Book.joins(:subjects)
        .where(subjects: { name: names })
        .group(:id)
        .having('count(*) = ?', names.size)
  end
end