ActiveRecord::Base.exists? returning 1 instead of true

Hi, I know 1 is truthy and nil is falsy, so it still does as described in the method documentation, but in previous versions it returned true/false (as I expect by its signature).

Is there a reason this has changed?

Thanks!

Ruby methods don't have signatures. :wink:

Hi, I know 1 is truthy and nil is falsy, so it still does as described in

the method documentation, but in previous versions it returned true/false
(as I expect by its signature).

In Ruby you should not expect true/false from a method whose name ends in ?
In Java they are the only allowed values, but in Ruby (as in Perl, C, and
many others) *any* value has an interpretation in boolean context.
Therefore you exploit that feature of the language.

From a method you have to expect what its contract guarantees.

Is there a reason this has changed?

The change happened here:

https://github.com/rails/rails/commit/ef64c6ba8c06f89995b4328d3468df9914e3c6b6

and made into 4.0.0 (3-2-stable still has the ternary).

The reason Rails in general does not commit to singletons in predicates is
that we do not want to write artificial code like the one in 3-2-stable. It
is ugly an unnecessary. Doing select_value we are done, so return right
there.

Documenting a generic predicate interface allows you that freedom. So you
use the predicate this way:

     do_foo if exists?

and you test it this way

    assert exists?

or

    exists?.should be_true

You never do

    do_foo if exists? == true

or

    exists?.should == true

If the caller needs a singleton, given our contracts, it is its
responsibility to get one out of the predicate:

    (!!exists?).to_json

or whatever.