[ActiveRecord] Find records with present attribute value more easily

Instead of: Person.where.not(name: nil)

``

Use:

Person.present(:name)

``

Avoids double negative and verbosity.

I’d be happy to contribute if there’s interest in this!

Alternative: Person.exists(:name)

``

Using "present’ might be confusing with the presence validation which is something different (a blank string is not present but is not nil either).

Best regards

Greg Navis

What about using “having”?

Person.having(:name)

``

class ApplicationRecord < ActiveRecord::Base

scope :not_blank, ->(field) { where.not(field => nil) } # or where.not(field => [‘’,nil]) depending on your needs

end

And you’re done.

As you can see above, what does ‘exists’ or ‘present’ mean? Not nil, or not nil and an empty string or maybe just not an empty string?

I like “having”. It reads more expressively than “present” and “exists”.

Could provide an option for including/excluding empty strings:

Person.having(:name, empty_strings: true)

``

By default, should it include or exclude empty strings?

Excluding nil and empty strings is probably more often the desired query. But possibly too magical as a default?

I don’t think these examples have much sway and the problem itself seems sufficiently solved by where.not(name: nil) to me. It’s clearer and does map nicely onto the resulting SQL.

Yes, sometimes Rails does relish syntactic sugar but that’s when it aids clarity.

PS. having is already taken: https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-having

I personally use where.not and find it clear enough as it its.

.exists doesn’t seem like a good name because it can confused with current exists?: ActiveRecord::FinderMethods

I don’t think “having” is a good idea since it already means something else in SQL: Having (SQL) - Wikipedia

I’ve personally missed the .present?-functionality from Object#present? for querying my models several times.

So I would argue, that in order to use the word “present” you would have to mimic the behaviour of Object#present?.

Then; I would use it.

Personally, if I would ever like to change it, I will go for something like Person.where(:name).is_not(nil) or Person.where(:name).is('Pikachu') or Person.where(:name).is_not(like: ['Pikachu', 'Raichu']) etc… Otherwise, I feel it already fine enough.

I agree that a double negative is iffy. But I don’t like present on the root. What I do like is: Person.where.present(:name) – so that #present on where becomes a modifier like #not. I would have to have the same semantics as Object#present?, though. So that means that both nil and empty would count. (Also agree that we can’t use #having since it already has meaning in SQL).

I like the idea of adding this to the where chain so you could do Person.where.blank(:name) and Person.where.present(:name). Joshua, let me know if you want to work together on a PR.