i did not know that

Posted by jcarroll

Sep 21

Here’s something I discovered the other day:

ActiveRecord infers model attributes from the database. Each attribute gets a getter, setter, and query method.

A query method? I know this is true for boolean columns but non boolean columns?

1
2
class User < ActiveRecord::Base
end
  users (id, name)
1
2
3
4
5
6
7
8
9
10
  def test_should_say_if_it_does_or_does_not_have_a_name_when_sent_name?
    user = User.new
    assert ! user.name?

    user.name = ''
    assert ! user.name?

    user.name = 'name'
    assert user.name?
  end

You get that query method for free for each of your ActiveRecord attributes. From this passing test it looks as if for strings its implemented in terms of String#blank?

This is nice because it can save you an extra message.

1
2
  if user.name.blank?
  end

becomes

1
2
  if ! user.name?
  end  

Comments on this post

Mr eel

Sep 21

Mr eel said,

That’s a good one. I use it heavily.

I do wish associations had similar methods though.

Joe Grossberg

Sep 21

Joe Grossberg said,

It still has its own set of rules though.

In that query method, nil and false eval to false. So do empty-string and zero.

But empty-array, empty-hash and 0.0 still evaluate to true. :(

grant

Sep 21

grant said,

looks like that method is defined by ActiveRecord::Base#define_question_method, which calls query_attribute:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        if attribute.kind_of?(Fixnum) && attribute == 0
          false
        elsif attribute.kind_of?(String) && attribute == "0"
          false
        elsif attribute.kind_of?(String) && attribute.empty?
          false
        elsif attribute.nil?
          false
        elsif attribute == false
          false
        elsif attribute == "f"
          false
        elsif attribute == "false"
          false
        else
          true
        end
Tammer Saleh

Sep 24

Tammer Saleh said,

Grant: That shows an important point to keep in mind when using model.field?

If field is set to “f” or “false”, then model.field? will be false, which might not have been what you were expecting. Consider user.sex?


Sorry, comments are closed for this article.

© 2000 - 2009 by thoughtbot, inc.
written by a bushel of tiny robots