Запрос в Active record с массивом хешей - PullRequest
0 голосов
/ 20 марта 2019

У меня есть следующая модель в Ruby

class Entity < ActiveRecord::Base
  validates :account_type, presence: true
  validates :account_id, presence: true
end

, и у меня есть массив хэшей, называемых учетными записями, например:

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

Итак, я хочу получить все сущностикоторые совпадают с элементами массива account (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

Но есть способ сделать это более эффективным??

Ответы [ 3 ]

2 голосов
/ 20 марта 2019

Учитывая это:

[{'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)) }
1 голос
/ 20 марта 2019

Если вы используете рельсы 5, вы можете попробовать or.Примерно так

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

Это всего лишь один SQL-запрос, но если массив большой, я не знаю, как это работает.

0 голосов
/ 20 марта 2019

Если у меня есть ваша проблема, это должно решить ее:

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

Позвольте мне объяснить, что происходит:

  • сначала метод map возвращает массиввсе записи, совпадающие с чем-либо в базе данных
  • , map взаимодействует через массив счетов, точно так же, как each, что означает, что он доставит данные по счетам в запрос where
  • a comma между where условия также работают для сравнений, если вы не делаете or, в случае, если я предполагаю, что вы можете использовать этот синтаксис: where('account_id = :id or account_type = :type', id: acc['account_id'], type: acc['account_type'])
...