【问题标题】:Rails: Filter ActiveRecord Search Results using CheckboxesRails:使用复选框过滤 ActiveRecord 搜索结果
【发布时间】:2016-09-24 19:31:24
【问题描述】:

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

我有一个包含三个模型的应用程序: 书 学科 图书主题

它们是这样关联的:

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 控制器,用户可以运行 Search 操作,该操作会呈现一个显示所有书籍的视图页面。通过选中侧边栏中的复选框(每个都标有主题名称),用户应该能够缩小适合他们搜索的书籍的数量。这是到目前为止的搜索操作:

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

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

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    我认为你的代码几乎没问题,但为什么你有having("count(*) &gt;= ?", 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
    

    【讨论】:

    • 感谢 names = params[:name].split(',') 行 - 这是我获取 names.size (用于计数行)所缺少的。然而,它仍然没有过滤——当我检查“历史”和“史诗”时,我仍然得到所有历史和史诗,而我只想要历史史诗。有什么想法吗?
    • 很奇怪。你能提供它生成的确切 SQL 吗?你可以看到它的服务器日志。
    • 没问题!选中一个框: Book Load (0.9ms) SELECT "books".* FROM "books" INNER JOIN "book_subjects" ON "book_subjects"."book_id" = "books"."id" INNER JOIN "subjects" ON "subjects "."id" = "book_subjects"."subject_id" WHERE "subjects"."name" = 'epic/saga' GROUP BY books.id HAVING count(*) >= 1
    • 选中了两个框:Book Load (1.0ms) SELECT "books".* FROM "books" INNER JOIN "book_subjects" ON "book_subjects"."book_id" = "books"."id" INNER JOIN "subjects" ON "subjects"."id" = "book_subjects"."subject_id" WHERE "subjects"."name" IN ('epic/saga', 'family') GROUP BY books.id HAVING count(* ) >= 2 但是这会返回相同数量的书籍。
    • 为什么还是&gt;=?在我的回答中,它只是=。请再试一次。
    猜你喜欢
    • 2012-01-14
    • 2021-08-20
    • 2015-04-27
    • 1970-01-01
    • 1970-01-01
    • 2015-07-10
    • 2018-11-02
    • 1970-01-01
    • 2012-08-30
    相关资源
    最近更新 更多