I can do this to check if a record(s) exists (say id "1" exists, but "2" and "3" don't):
Model.exists?(:id => [1, 2, 3]) #=> true
How do I do the opposite, so:
Model.not_exists?(:id => [1, 2, 3]) #=> true
I can do this to check if a record(s) exists (say id "1" exists, but "2" and "3" don't):
Model.exists?(:id => [1, 2, 3]) #=> true
How do I do the opposite, so:
Model.not_exists?(:id => [1, 2, 3]) #=> true
Edit: Please don't use this method. Even if it works it's not optimal since it loads all records instead of only testing their existence. This is a better way of doing it.
If you only need search records through ID you can try this
class Model
def self.not_exists?(ids)
self.find(ids)
false
rescue
true
end
end
If any of the IDs does not exist the find
method will raise a ActiveRecord::RecordNotFound exception that we simply catch and return true.
just add a ! operator
!Model.exists?(:id => [1, 2, 3]) #=> true
2
and 3
don't exist, how to make it return false. !Model.exists?(:id => [1, 2, 3])
returns false
if 1
exists, whereas I want Model.not_exists?(:id => [1, 2, 3])
to return true if any don't exist. –
Bluecollar Model.find(ids_ary).count
then rescue ActiveRecord::RecordNotFound
–
Hydrostat Use empty?
, this is what you want. It uses count(*)
vs select 1 as one
.
> Rocketeer.where(:id => [1, 2, 3]).empty?
(0.6ms) SELECT COUNT(*) FROM "rocketeers" WHERE "rocketeers"."id" IN (1, 2, 3)
=> false
> Rocketeer.where(:id => [1, 2, 3]).any?
(0.5ms) SELECT COUNT(*) FROM "rocketeers" WHERE "rocketeers"."id" IN (1, 2, 3)
=> true
> Rocketeer.where(:id => [1, 2, 3]).exists?
Rocketeer Exists (0.5ms) SELECT 1 AS one FROM "rocketeers" WHERE "rocketeers"."id" IN (1, 2, 3) LIMIT 1
=> true
SELECT 1 AS one ... LIMIT 1
more efficient than SELECT COUNT(*)
? –
Riebling limit 1
is equal or faster than count(*)
. Although generally it'll be only perceptible with a combination of table size and index keys. Also, favor use of empty?
to save DB RTT, if you'll use matching records. –
Pye Edit: Please don't use this method. Even if it works it's not optimal since it loads all records instead of only testing their existence. This is a better way of doing it.
If you only need search records through ID you can try this
class Model
def self.not_exists?(ids)
self.find(ids)
false
rescue
true
end
end
If any of the IDs does not exist the find
method will raise a ActiveRecord::RecordNotFound exception that we simply catch and return true.
find
will load the records where you only care at the existence of a raw. Answer belong should be the one accepted –
Barnstorm A more Ruby-esque way of doing it would be to use unless
with exists?
. This way, you don't have to use !
. I imagine your use case is something like this:
def my_method
return unless Model.exists?(:id => [1, 2, 3])
# do something
end
You can replace 1, 2, 3
with a variable (call it id
or something) and even remove the array altogether if you'd like: .exists?(id: id)
class Model
def self.does_not_exist?(ids)
Model.where(id: ids).count < ids.size
end
end
Explanation: If (and only if) all the instances you're looking for exist, Model.where(id: ids).count
is equal to ids.size
.
However if there are one or more instances missing, the count will be lower, meaning that there's a record that does not exist.
COUNT
in SQL which counts every row in a table. where(id: [1, 2, 3]).exists?
on the other hand does a SELECT... WHERE... LIMIT 1
which will return first row it finds. See @Brufsky 's answer. –
Binni Another simple way is to use the where method with an array of id's.
# If the count of the query is equal to the count of all of the id's then the statement will return false.
# Else it will return true if not all ids exists in the database.
Model.where(id: [1, 2, 3]).count < [1,2,3].count
To ensure all ids exist, not just one the following works without have to rescue
ids = [1,2,3]
Model.where(id: ids).count != ids.length
The exists? method will return true if any of the ids match. The above will ensure all ids exist.
.none?
returns true if there are no records.
Model.none?(id: [1, 2, 3])
© 2022 - 2024 — McMap. All rights reserved.
find
will load the records where you only care at the existence of a raw. Answer belong should be the one accepted – Barnstorm