使用散列数组在活动记录中查询

Query in Active record with an array of hash

我在Ruby

中有以下模型
class Entity < ActiveRecord::Base
  validates :account_type, presence: true
  validates :account_id, presence: true
end

我有一个名为 accounts 的哈希数组,类似于:

[{'account_id':44, 'account_type':'user'},..,{'account_id':44, 'account_type':'other'}, {'account_id':88,
'account_type':'another'}]

所以我想要一种方法来获取与帐户数组元素匹配的所有实体(account_id 和 account_type 同时进行。

我尝试使用此代码:

entities = []
accounts.each do |account|
    entities << Entity.where(account_id: ActiveSupport::HashWithIndifferentAccess.new(account)['account_id'])
    .where(account_type: ActiveSupport::HashWithIndifferentAccess.new(account)['account_type'])
end

但是有一种方法可以更有效地做到这一点??

如果您使用的是 rails 5,您可以尝试 or。像这样

entities = Entity.none
items.each do |item|
  entities = entities.or(Entity.where(item))
end

这只是一个 SQL 查询,但如果数组很大,我不知道它是如何工作的。

鉴于此:

[{'account_id':44, 'account_type':'user'}, {'account_id':44, 'account_type':'other'}, ... ]

你想要的SQL是:

select ...
where account_id = 44 and account_type = 'user'
   or account_id = 44 and account_type = 'other'
   or ...

请注意,SQL 的运算符优先级与以下内容相同:

select ...
where (account_id = 44 and account_type = 'user')
   or (account_id = 44 and account_type = 'other')
   or ...

您可以使用 ActiveRecord 构建这样的查询,但由于 #or 的工作方式,它有点麻烦:

accounts = your_array_of_hashes
entities = accounts.inject(Entity.none) { |memo, h| memo.or(Entity.where(h)) }

如果我遇到你的问题,这应该可以解决:

entities = accounts.map { |acc| Entity.where(account_id: acc['account_id'], account_type: acc['account_type']) }

让我解释一下发生了什么:

  • 首先,方法 map returns 数组将与数据库中的任何内容匹配的所有条目
  • map 正在通过帐户数组进行交互,就像 each 一样,这意味着它将把帐户中的数据带到 where 查询
  • a comma between where conditions 也适用于比较,除非你正在做一个 or,在这种情况下我想你可以使用这个语法:where('account_id = :id or account_type = :type', id: acc['account_id'], type: acc['account_type'])