Reputation: 397
I have the following model in Ruby
class Entity < ActiveRecord::Base
validates :account_type, presence: true
validates :account_id, presence: true
end
and I have an array of hashes called accounts something like:
[{'account_id':44, 'account_type':'user'},..,{'account_id':44, 'account_type':'other'}, {'account_id':88,
'account_type':'another'}]
So I want a way to obtain all the entities that match with the elements of the accounts array (account_id and account_type both at same time).
I tried using this code:
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
But there is a way to do it more efficient ??
Upvotes: 0
Views: 2697
Reputation: 301
If i got your problem, this should solve it:
entities = accounts.map { |acc| Entity.where(account_id: acc['account_id'], account_type: acc['account_type']) }
Let me explain what is happening:
map
returns an array will all the entries that dit match with anything at the databasemap
is interating through the accounts array, just like the each
, which means it will bring the data at accounts to the where
querycomma
between where
conditions also works for comparisons, unless you are doing an or
, in the case i suppose you can use this syntax: where('account_id = :id or account_type = :type', id: acc['account_id'], type: acc['account_type'])
Upvotes: 0
Reputation: 30056
If you're using rails 5 you could try or
. Something like this
entities = Entity.none
items.each do |item|
entities = entities.or(Entity.where(item))
end
This is just one SQL query but if the array is big I don't know how this works.
Upvotes: 1
Reputation: 434665
Given this:
[{'account_id':44, 'account_type':'user'}, {'account_id':44, 'account_type':'other'}, ... ]
the SQL you want is:
select ...
where account_id = 44 and account_type = 'user'
or account_id = 44 and account_type = 'other'
or ...
Note that SQL's operator precedence makes that the same as:
select ...
where (account_id = 44 and account_type = 'user')
or (account_id = 44 and account_type = 'other')
or ...
You can build a query like that using ActiveRecord but it is a little cumbersome due to the way #or
works:
accounts = your_array_of_hashes
entities = accounts.inject(Entity.none) { |memo, h| memo.or(Entity.where(h)) }
Upvotes: 3