when is a boolean not a boolean?

Weird problem.. I'm new to rails and ruby... maybe someone can explain what I am not getting..

Env: Mac OS X 10.5.3, Rails. 2.0.2, ruby 1.8.6 (2007-09-24 patchlevel 111)

A User class created using the restful_authentication plugin

A Company class (has lots of fields not really important to the problem below)

Users can have many companies, entered into the User.rb model as one would expect       has_many: :companies

In the User.rb model I've also added:

def has_companies?     !companies.empty?   end

..and..

def company_count        companies.size      end

so I can easily find out if they actually have any companies and how many companies they have. Pretty straight-forward, right?

I create users, every thing looks fine; I ask the user if it has any companies, if returns "false" as in:

u1 = User.find(1)

=> #<User id: 1, login: "admin", email: "info@yourapplication.com", crypted_password: "85795571cc9fd37cb7c37827f8cf6b3abd26c4e7", salt:     :     :

u1.has_companies?

=> false

In my view, if the user has previously entered company info, I want to give them a summary, if they have no companies they are offered a link to create one. very simplistic:

<% if @user.has_companies? %>     this user has <%= @user.company_count %> companies (has_companies? is <%= @user.has_companies? %>) .... <br> <% else %> <%= link_to "Please enter some basic info about your company", "/ companies/new" %> <% end %>

Oddly, when this view is executed, the following is displayed:

     this user has 0 companies (has_companies? is false) ....

It's as if the <% if.. clause doesn't know how to handle the evaluation of a boolean.

If I change the test to be <% if @user.has_companies? == false %> it works as expected.

wtf? Why would ruby not be able to grok a boolean test? What am I missing Any suggestions??

_DHMS

Step through it in the debugger to see if it's really executing what you thing it is?

Fred

The issue might be nil objects that are never true nor false. ...

Have a look at this article that I found interesting:

http://toolmantim.com/article/2007/3/26/bangbang_your_nil_is_dead

For the purposes of a condition, nil is false. (but of course nil == false is false, but if you're sane you'll never be explicitly be testing for == false or == true).

Fred

Actually nil is always logically false.

http://www.therailsway.com/2007/8/1/dangers-of-cargo-culting

Actually it's a little more direct than that. In Rails 2.0.2, testing a has_many relationship will return an empty array if, in fact, there are no elements connected to the source record.

My "has_companies?" method is this:

  def has_companies?     !companies.empty?   end

what it returns <b>is a boolean</b>. In fact, if you look at my original post, I AM getting back "false" but the <% if... %> test in the erb in the view code isn't treating it as a boolean. Any ideas?

<what it returns <b>is a boolean</b>. In fact, if you look at my...

I copied this from Boolean data type - Wikipedia

begin Quote The Ruby programming language does not have a Boolean data type as part of the language. Like many other interpreted languages, all variables are dynamically typed. Instead, ruby defines the explicit values of false and nil, and everything else is considered true, including 0, , and the empty string "". The values true, false, and nil can be assigned to variables, returned from functions or methods, and compared in Boolean expressions.

a = 0 if (a)   print "true" else   print "false" end

will print "true", which might come as a surprise to a new user of the language.

End Quote

I think you problem stems from applying a logical "NOT" operator to something that is not what you expect. Does !companies get evaluated before or after !companies.empty? ! companies could be returning true before !companies.empty? gets evaluated.

Just a guess, You have to step through the code.

well you know it returns false the second time, but that's not quite the same thing. Anyway, i'll reiterate my suggestion to step through it in the debugger and work out exactly what is happening.

Fred