如何通过多个值(或)筛选模型字段

时间:2019-02-27 21:45:03

标签: javascript ruby-on-rails ruby input-filtering

我有一个模型Book,它具有以下范围函数:

scope :author, lambda { |author|
    return where(nil) unless author.present?
    joins(:author).where('author.id' => author)
  }

这可以仅使用一个作者值来过滤书籍。我想做的是,我从一个JavaScript文件传递了一个数组,该文件是一个作者列表,例如:["harry", "doyle", "alex", "parrish"],并且我希望能够找到所有具有这些作者中的任何一个的书籍(因此或在这里查询)。请注意,每本书可以有多位作者。

我尝试了以下功能,但是它只是给我所有的书,而不是如上所述的正确过滤。

scope :authors_multiple, lambda { |authors|
  @results = Book
  authors.each do |auth|
    @results = @results.author(auth)
  end
  return @results
}

模型作者(摘录):

class Author < ApplicationRecord
  has_and_belongs_to_many :books, uniq: true
  ....

模型书(摘录):

class Book < ApplicationRecord
  has_and_belongs_to_many :authors, uniq: true
  ....

能否请您帮助我了解我做错了什么或做对的正确方法。预先感谢。

4 个答案:

答案 0 :(得分:0)

authors = ["harry", "doyle", "alex", "parrish"]  
Book.where(author: authors)

authors = ["harry", "doyle", "alex", "parrish"]  
auths = Author.where(name: authors)
Book.where(author: auths)

这假设作者有很多书。 您可以在此处了解有关模型关联的更多信息:https://guides.rubyonrails.org/association_basics.html

答案 1 :(得分:0)

首先,您需要获取Author记录。如何完成取决于您的架构和数据,但这将类似于:

author_names = ["harry", "doyle", "alex", "parrish"]

然后执行以下操作之一:

authors = Author.where(name: author_names)
authors = Author.where("name ILIKE ANY ( array[?] )", author_names.map { |name| "%#{name}%" })

让我们ActiveRecord::Relation吸引了我们所需的作者。一旦有了作者,我们可以将其与我们的书合并以获得我们想要的所有书:

books = Book.joins(:authors).merge(authors)

请注意,连接位于复数作者 s 上。 Rails将知道要通过连接表(默认为authors_booksauthors表进行连接。

答案 2 :(得分:0)

您会看到一组作者姓名,对吧?

scope :by_author, lambda { |names|
  # if you have a chance to get blank values you need to reject them
  names.reject!(&:blank?) if names.is_a? Array

  joins(:authors).where(authors: { name: names }).distinct if names.present?
}

它应该与数组或字符串参数一起正常工作

Book.by_author(["harry", "doyle"])
Book.by_author("harry")

答案 3 :(得分:0)

尝试以下代码:

authors = ["harry", "doyle", "alex", "parrish"]    
Book.joins(:authors).where(:authors => {:name => authors})