1

我有一个基本的 has_many 关系,建模如下:

class Term < ActiveRecord::Base
    has_many :acroynms
end

class Acronym < ActiveRecord::Base
    belongs_to :term    
end

我想写一个 arel 关系,它将根据术语的名称或首字母缩略词的名称提取术语。我的关系不正确,但我想做一些看起来像这样的事情:

terms = Term.arel_table
relation = terms[name].matches("%#{params['a']}%")
relation = relation.or(terms[:acronyms.name].matches("%#{params['a']}%"))
@results = Term.where(relation)

我想将它保留在关系中,因为我将许多其他组合条件组合到该关系中(为简洁起见,我在此省略)。

我正在使用关系,而不是仅仅在最后一行将所有内容组合在一起,需要组合的项目直到运行时才会知道,具体取决于用户输入。我的想法是使用这个模型,我将能够设置我的关系,无论它可能多么复杂,然后只需要一行来设置@results,而不管用户输入如何。

有没有办法把这一切写成关系?否则,我想我需要求助于使用 arel 的联接,但仅在用户输入需要它的情况下才加入,对吗?

4

2 回答 2

1

我不完全确定如何使用 arel 来执行此操作,但如果您想where基于参数(或其他输入)链接子句,则可以执行以下操作:

query = User.scoped

query = query.where("name like ?", "%#{params[:name]}%") if params[:name].present?
query = query.where("email like ?", "%#{params[:email]}%") if params[:email].present?

@users = query.all

同样,我知道这不完全是你想要的,但可能是一个可能的选择。

注意:如果您在控制台中运行它,这将不会达到您的预期,因为printREPL 的步骤将执行每个步骤,这使得它看起来像多个查询,而在 Rails 应用程序中它实际上只执行一个。

于 2013-11-11T00:57:34.230 回答
0

为了解决使用 OR 运算符的问题,我通过使用 3 个查询来解决这个问题,这是次优的,但很实用。

我的第一个查询查找名称类似于搜索参数的首字母缩略词。

acronymQuery = query.includes(:acronyms).where('acronyms.name like ?', wildcard_search).select("terms.id")

第二个查找名称类似于搜索参数的术语。

termQuery = query.where('terms.name like ?', wildcard_search).select("terms.id")

然后我结合每个查询的唯一 ID,我的第三个查询搜索这些 ID。

acronymQueryResults = acronymQuery.all.map {|row| row.id}
termQueryResults = termQuery.all.map {|row| row.id}
ids = (acronymQueryResults + termQueryResults).uniq
query = Term.where('id' => ids)
于 2013-12-18T15:50:23.997 回答